home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianDraw.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  63KB  |  2,714 lines

  1. /*ScianDraw.c
  2.   Drawing routines for various types of objects
  3.   Eric Pepke
  4.   March 28, 1990
  5. */
  6.  
  7. /* JEL added PostScript drawing 4/2/92 */
  8.  
  9. #include "Scian.h"
  10. #include "ScianTypes.h"
  11. #include "ScianArrays.h"
  12. #include "ScianLists.h"
  13. #include "ScianIDs.h"
  14. #include "ScianWindows.h"
  15. #include "ScianDraw.h"
  16. #include "ScianObjWindows.h"
  17. #include "ScianColors.h"
  18. #include "ScianPictures.h"
  19. #include "ScianStyle.h"
  20. #include "ScianFontSystem.h"
  21.  
  22. extern short LinToGamma[];
  23.  
  24. DrawingState drawingStates[NDRAWINGSTATES];    /*Stack of drawing states*/
  25. int curDrawingStateIndex = 0;            /*Current drawing state*/
  26.  
  27. Bool drawMouse = false;                /*True iff draw on next mouse*/
  28. extern int curMouse;                /*Current mouse button*/
  29.  
  30. int drawingMode = DRAW_SCREEN;            /*Drawing to the screen*/
  31. FILE *drawFile = 0;                /*File in which to draw*/
  32.  
  33. int imageSubSample = 0;                /*Subsampling offset for image*/
  34.  
  35. Bool fullScreen = false;            /*True iff drawing to full screen*/
  36.  
  37. Matrix Identity = {{1.0, 0.0, 0.0, 0.0},
  38.            {0.0, 1.0, 0.0, 0.0},
  39.            {0.0, 0.0, 1.0, 0.0},
  40.            {0.0, 0.0, 0.0, 1.0}};
  41.  
  42. /* globals used for PostScript drawing */
  43. FILE *psFile;        /* pointer to temp file */
  44. int iconsUsed[32];    /* maximum number of *different* icons in EPS file is 32 */
  45. int numIconsUsed;    /* number used so far = next index to use */
  46. Bool evenOnly = false;
  47. Bool oddOnly = false;
  48.  
  49. #ifdef PROTO
  50. void BeginTranslucent(void)
  51. #else
  52. void BeginTranslucent()
  53. #endif
  54. /*Begins translucent drawing*/
  55. {
  56. #ifdef GRAPHICS
  57.     if (evenOnly)
  58.     {
  59.     setpattern(EVENGREYPAT);
  60.     }
  61.     else if (oddOnly)
  62.     {
  63.     setpattern(ODDGREYPAT);
  64.     }
  65.     else
  66.     {
  67.     setpattern(GREYPAT);
  68.     }
  69. #endif
  70. }
  71.  
  72. #ifdef PROTO
  73. void EndTranslucent(void)
  74. #else
  75. void BeginTranslucent()
  76. #endif
  77. /*Begins translucent drawing*/
  78. {
  79. #ifdef GRAPHICS
  80.     if (evenOnly)
  81.     {
  82.     setpattern(EVENPAT);
  83.     }
  84.     else if (oddOnly)
  85.     {
  86.     setpattern(ODDPAT);
  87.     }
  88.     else
  89.     {
  90.     setpattern(SOLIDPAT);
  91.     }
  92. #endif
  93. }
  94.  
  95. #ifdef PROTO
  96. void BeginEvenOnly(void)
  97. #else
  98. void BeginEvenOnly()
  99. #endif
  100. /*Begins drawing on only even lines*/
  101. {
  102.     evenOnly = true;
  103. #ifdef GRAPHICS
  104.     setpattern(EVENPAT);
  105. #endif
  106. }
  107.  
  108. #ifdef PROTO
  109. void EndEvenOnly(void)
  110. #else
  111. void EndEvenOnly()
  112. #endif
  113. /*Ends drawing on only even lines*/
  114. {
  115.     evenOnly = false;
  116. #ifdef GRAPHICS
  117.     setpattern(SOLIDPAT);
  118. #endif
  119. }
  120.  
  121. #ifdef PROTO
  122. void BeginOddOnly(void)
  123. #else
  124. void BeginOddOnly()
  125. #endif
  126. /*Begins drawing on only odd lines*/
  127. {
  128.     oddOnly = true;
  129. #ifdef GRAPHICS
  130.     setpattern(ODDPAT);
  131. #endif
  132. }
  133.  
  134. #ifdef PROTO
  135. void EndOddOnly(void)
  136. #else
  137. void EndEvenOnly()
  138. #endif
  139. /*Ends drawing on only odd lines*/
  140. {
  141.     oddOnly = false;
  142. #ifdef GRAPHICS
  143.     setpattern(SOLIDPAT);
  144. #endif
  145. }
  146.  
  147. #if 0
  148. void EchoDraw(s)
  149. char *s;
  150. {
  151.     int k;
  152.     for (k = 0; k < curDrawingStateIndex; ++k) printf("  ");
  153.     printf("%s\n", s);
  154. }
  155. #else
  156. #define EchoDraw(s)
  157. #endif
  158.  
  159. #ifdef PROTO
  160. void PushTransformation(void)
  161. #else
  162. void PushTransformation()
  163. #endif
  164. /*Pushes the transformation*/
  165. {
  166. #ifdef GRAPHICS
  167.     pushmatrix();
  168. #endif
  169. }
  170.  
  171. #ifdef PROTO
  172. void PopTransformation(void)
  173. #else
  174. void PopTransformation()
  175. #endif
  176. /*Pushes the transformation*/
  177. {
  178. #ifdef GRAPHICS
  179.     popmatrix();
  180. #endif
  181. }
  182.  
  183. void PushDrawingState()
  184. /*Pushes the drawing state, producing a copy of the top drawing state*/
  185. {
  186.     int k;
  187.  
  188.     ++curDrawingStateIndex;
  189.     if (curDrawingStateIndex >= NDRAWINGSTATES)
  190.     {
  191.     fprintf(stderr, "SciAn: Panic, drawing state overflow\n");
  192.     exit(-1);
  193.     }
  194.  
  195.     CURSTATE . window = LASTSTATE . window;
  196.     CURSTATE . initialWindow = false;
  197.     for (k = 0; k < 4; ++k)
  198.     {
  199.     CURSTATE . screenMask[k] = LASTSTATE . screenMask[k];
  200.     CURSTATE . viewport[k] = LASTSTATE . viewport[k];
  201.     }
  202.     for (k = 0; k < 2; ++k)
  203.     {
  204.     CURSTATE . origin[k] = LASTSTATE . origin[k];
  205.     CURSTATE . translation[k] = LASTSTATE . translation[k];
  206.     }
  207. }
  208.  
  209. void PopDrawingState()
  210. /*Pops the drawing state and sets everything back to what it was.
  211.   As a side-effect, may set the window*/
  212. {
  213.     Bool setViewport = false;    /*True iff the viewport needs to be set*/
  214.  
  215.     --curDrawingStateIndex;
  216.  
  217.     if (curDrawingStateIndex < 0)
  218.     {
  219.     fprintf(stderr, "SciAn: Panic, drawing state underflow\n");
  220.     exit(-1);
  221.     }
  222.  
  223.     if (!(CURSTATE . window))
  224.     {
  225.     /*No window, do nothing*/
  226.     return;
  227.     }
  228.  
  229.     if (NEXTSTATE . initialWindow)
  230.     {
  231.     /*New window!  Need to set everything*/
  232.     SelWindow(CURSTATE . window);
  233.  
  234. #ifdef GRAPHICS
  235.     shademodel(FLAT);
  236.     concave(TRUE);
  237.     backface(FALSE);
  238.     lmcolor(LMC_COLOR);
  239.     {
  240.         float n[3];
  241.         n[0] = 0.0;
  242.         n[1] = 0.0;
  243.         n[2] = 1.0;
  244.         N3F(n);
  245.     }
  246. #endif
  247.     setViewport = true;
  248.     }
  249.  
  250.     if (setViewport ||
  251.     (CURSTATE . viewport[0] != NEXTSTATE . viewport[0]) ||
  252.     (CURSTATE . viewport[1] != NEXTSTATE . viewport[1]) ||
  253.     (CURSTATE . viewport[2] != NEXTSTATE . viewport[2]) ||
  254.     (CURSTATE . viewport[3] != NEXTSTATE . viewport[3]))
  255.     {
  256.     /*New viewport.  Need to set viewport*/
  257.     setViewport = true;
  258.  
  259. #ifdef GRAPHICS
  260.     if (drawingMode == DRAW_SCREEN)
  261.     {
  262.         /*Set the viewport in pixel-centered coordinates*/
  263.         viewport((Screencoord) CURSTATE . viewport[0],
  264.          (Screencoord) CURSTATE . viewport[1] - 1, 
  265.          (Screencoord) CURSTATE . viewport[2],
  266.          (Screencoord) CURSTATE . viewport[3] - 1);
  267.  
  268.         /*Set up an orthographic perspective setup to map to this viewport*/
  269.         MakeOrthoXform();
  270.     }
  271.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  272.     {
  273.         fprintf(psFile, "%%new viewport\n%d %d translate\n",
  274.         (int) CURSTATE . translation[0], (int) CURSTATE . translation[1]);
  275.  
  276.     }
  277. #endif
  278.     }
  279.  
  280.     if (setViewport || 
  281.     (CURSTATE . screenMask[0] != NEXTSTATE . screenMask[0]) ||
  282.     (CURSTATE . screenMask[1] != NEXTSTATE . screenMask[1]) ||
  283.     (CURSTATE . screenMask[2] != NEXTSTATE . screenMask[2]) ||
  284.     (CURSTATE . screenMask[3] != NEXTSTATE . screenMask[3]))
  285.     {
  286.     /*New screen mask.  Need to set it*/
  287.  
  288.     if (drawingMode == DRAW_SCREEN)
  289.     {
  290. #ifdef GRAPHICS
  291.         scrmask((Screencoord) CURSTATE . screenMask[0],
  292.         (Screencoord) CURSTATE . screenMask[1] - 1, 
  293.         (Screencoord) CURSTATE . screenMask[2],
  294.         (Screencoord) CURSTATE . screenMask[3] - 1);
  295. #endif
  296.     }
  297.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  298.     {
  299.         int sl, sr, sb, st;
  300.         sl = CURSTATE . screenMask[0];
  301.         sr = CURSTATE . screenMask[1];
  302.         sb = CURSTATE . screenMask[2];
  303.         st = CURSTATE . screenMask[3];
  304.  
  305.         fprintf(psFile,
  306. "resetclip newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath clip newpath\n",
  307.         sl, st, sr, st, sr, sb, sl, sb);
  308.     }
  309.     }
  310.  
  311.     if ((setViewport == false) &&
  312.     (CURSTATE . translation[0] != NEXTSTATE . translation[0] ||
  313.      CURSTATE . translation[1] != NEXTSTATE . translation[1]))
  314.     {
  315.     if (drawingMode == DRAW_SCREEN)
  316.     {
  317. #ifdef GRAPHICS
  318.         /*Translate back, but only if only the translation is different*/
  319.         translate(    (Coord) (CURSTATE . translation[0] - NEXTSTATE . translation[0]),
  320.             (Coord) (CURSTATE . translation[1] - NEXTSTATE . translation[1]),
  321.             (Coord) 0.0);
  322. #endif
  323.     }
  324.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  325.     {
  326.             fprintf(psFile, "%d %d translate\n",
  327.             (int) (CURSTATE . translation[0] - NEXTSTATE . translation[0]),
  328.         (int) (CURSTATE . translation[1] - NEXTSTATE . translation[1]));
  329.     }
  330.     }
  331. }
  332.  
  333. #ifdef PROTO
  334. void SetDrawingWindow(WinInfoPtr window)
  335. #else
  336. void SetDrawingWindow(window)
  337. WinInfoPtr window;
  338. #endif
  339. /*Sets to draw into a new window.  Side effect--selects the window*/
  340. {
  341.     int k;
  342.     int l, r, b, t, ox, oy;
  343.  
  344.     EchoDraw("SetDrawingWindow");
  345.  
  346.     /*Save the current window, etc.*/
  347.     PushDrawingState();
  348.  
  349.     /*Select this window and use it*/
  350.     SelWindow(window);
  351. #ifdef GRAPHICS
  352.     shademodel(FLAT);
  353.     concave(TRUE);
  354.     backface(FALSE);
  355.     lmcolor(LMC_COLOR);
  356.     {
  357.         float n[3];
  358.         n[0] = 0.0;
  359.         n[1] = 0.0;
  360.         n[2] = 1.0;
  361.         N3F(n);
  362.     }
  363. #endif
  364.  
  365.     CURSTATE . window = window;
  366.     CURSTATE . initialWindow = true;
  367.  
  368.     /*Zero translation*/
  369.     for (k = 0; k < 2; ++k)
  370.     {
  371.     CURSTATE . translation[k] = 0;
  372.     }
  373.  
  374.     /*Get the bounds of the window, in Mac style coordinates*/
  375.     GetWindowBounds(&l, &r, &b, &t);
  376.  
  377.     /*Save the bounds as the viewport and mask*/
  378.     CURSTATE . screenMask[0] = CURSTATE . viewport[0] = l;
  379.     CURSTATE . screenMask[1] = CURSTATE . viewport[1] = r;
  380.     CURSTATE . screenMask[2] = CURSTATE . viewport[2] = b;
  381.     CURSTATE . screenMask[3] = CURSTATE . viewport[3] = t;
  382.  
  383.     /*Get the origin of the window*/
  384.     GetWindowOrigin(&ox, &oy);
  385.     CURSTATE . origin[0] = ox;
  386.     CURSTATE . origin[1] = oy;
  387.     
  388. #ifdef GRAPHICS
  389.     if (drawingMode == DRAW_SCREEN)
  390.     {
  391.     /*Set the viewport in pixel-centered coordinates*/
  392.     viewport((Screencoord) l, (Screencoord) r - 1, 
  393.      (Screencoord) b, (Screencoord) t - 1);
  394.  
  395.     /*Set up an orthographic perspective setup to map to this viewport*/
  396.     MakeOrthoXform();
  397.     }
  398. #endif
  399. }
  400.  
  401. void RestoreDrawingWindow()
  402. /*Restores the window area to what it was before.  Side effect--sets the
  403.   window*/
  404. {
  405.     /*Pop the drawing state*/
  406.     PopDrawingState();
  407.     EchoDraw("RestoreDrawingWIndow");
  408. }
  409.  
  410. #ifdef PROTO
  411. void SetSubPort(int l, int r, int b, int t)
  412. #else
  413. void SetSubPort(l, r, b, t)
  414. int l, r, b, t;
  415. #endif
  416. /*Sets to draw into a subport.  Side effect--selects the window*/
  417. {
  418.     int k;
  419.  
  420.     EchoDraw("SetSubPort");
  421.  
  422.     /*Save the current state.*/
  423.     PushDrawingState();
  424.  
  425.     /*Pretend its a new window*/
  426.     CURSTATE . initialWindow = true;
  427.  
  428.     /*Save the bounds as the viewport*/
  429.     CURSTATE . viewport[0] = l;
  430.     CURSTATE . viewport[1] = r;
  431.     CURSTATE . viewport[2] = b;
  432.     CURSTATE . viewport[3] = t;
  433.  
  434.     /*Shift the mask over by the effective offset*/
  435.     CURSTATE . screenMask[0] -= CURSTATE . translation[0];
  436.     CURSTATE . screenMask[1] -= CURSTATE . translation[0];
  437.     CURSTATE . screenMask[2] -= CURSTATE . translation[1];
  438.     CURSTATE . screenMask[3] -= CURSTATE . translation[1];
  439.  
  440.     /*Make a screen mask that is the intersection*/
  441.     if (CURSTATE . viewport[0] > CURSTATE . screenMask[0])
  442.     CURSTATE . screenMask[0] = CURSTATE . viewport[0];
  443.     if (CURSTATE . viewport[1] < CURSTATE . screenMask[1])
  444.     CURSTATE . screenMask[1] = CURSTATE . viewport[1];
  445.     if (CURSTATE . viewport[2] > CURSTATE . screenMask[2])
  446.     CURSTATE . screenMask[2] = CURSTATE . viewport[2];
  447.     if (CURSTATE . viewport[3] < CURSTATE . screenMask[3])
  448.     CURSTATE . screenMask[3] = CURSTATE . viewport[3];
  449.  
  450.     /*Zero translation*/
  451.     for (k = 0; k < 2; ++k)
  452.     {
  453.     CURSTATE . translation[k] = 0;
  454.     }
  455.  
  456.     /*Bump up origin*/
  457.     CURSTATE . origin[0] += l;
  458.     CURSTATE . origin[1] += b;
  459.  
  460.     /*Save the bounds as the viewport and mask*/
  461.     CURSTATE . screenMask[0] = CURSTATE . viewport[0] = l;
  462.     CURSTATE . screenMask[1] = CURSTATE . viewport[1] = r;
  463.     CURSTATE . screenMask[2] = CURSTATE . viewport[2] = b;
  464.     CURSTATE . screenMask[3] = CURSTATE . viewport[3] = t;
  465.  
  466. #ifdef GRAPHICS
  467.     if (drawingMode == DRAW_SCREEN)
  468.     {
  469.     /*Set the viewport in pixel-centered coordinates*/
  470.     viewport((Screencoord) l, (Screencoord) r - 1, 
  471.          (Screencoord) b, (Screencoord) t - 1);
  472.  
  473.     /*Set up an orthographic perspective setup to map to this viewport*/
  474.     MakeOrthoXform();
  475.  
  476.     /*Set the screen mask*/
  477.     scrmask((Screencoord) CURSTATE . screenMask[0],
  478.         (Screencoord) CURSTATE . screenMask[1] - 1, 
  479.         (Screencoord) CURSTATE . screenMask[2],
  480.         (Screencoord) CURSTATE . screenMask[3] - 1);
  481.     }
  482.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  483.     {
  484.     fprintf(psFile, "%%Call to SetSubPort!\n");
  485.     }
  486. #endif
  487. }
  488.  
  489. void RestoreSubPort()
  490. /*Restores the window area to what it was before.  Side effect--sets the
  491.   window*/
  492. {
  493.     /*Pop the drawing state*/
  494.     PopDrawingState();
  495.     EchoDraw("RestoreSubPort");
  496. }
  497.  
  498. #ifdef PROTO
  499. void SetOrthoPick(void)
  500. #else
  501. void SetOrthoPick()
  502. #endif
  503. /*Sets to do an ortho pick.*/
  504. {
  505.     int k;
  506.  
  507.     EchoDraw("SetOrthoPick");
  508.  
  509.     /*Save the current state.*/
  510.     PushDrawingState();
  511.  
  512.     /*Pretend its a new window*/
  513.     CURSTATE . initialWindow = true;
  514. }
  515.  
  516. #ifdef PROTO
  517. void RestoreOrthoPick(void)
  518. #else
  519. void RestoreOrthoPick()
  520. #endif
  521. /*Restores the pickiness to what it was before.  Side effect--sets the
  522.   window*/
  523. {
  524.     /*Pop the drawing state*/
  525.     PopDrawingState();
  526.     EchoDraw("RestoreOrthoPick");
  527. }
  528.  
  529. void SetOrigin(x, y)
  530. int x, y;
  531. /*Sets the origin to x, y WITHIN current translation*/
  532. {
  533.     EchoDraw("SetOrigin");
  534.     /*Save drawing state*/
  535.     PushDrawingState();
  536.   
  537.     CURSTATE . translation[0] += x;
  538.     CURSTATE . translation[1] += y;
  539.  
  540.     if (drawingMode == DRAW_SCREEN)
  541.     {
  542. #ifdef GRAPHICS
  543.     translate((Coord) x, (Coord) y, (Coord) 0.0);
  544. #endif
  545.     }
  546.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  547.     {
  548.         fprintf(psFile, "%d %d translate\n", x, y);
  549.     }
  550. }
  551.  
  552. void RestoreOrigin()
  553. /*Restores the origin to what it was*/
  554. {
  555.     PopDrawingState();
  556.     EchoDraw("RestoreOrigin");
  557. }
  558.  
  559. #ifdef PROTO
  560. void FullScreen(Bool whether)
  561. #else
  562. void FullScreen(whether)
  563. Bool whether;
  564. #endif
  565. /*Sets full screen mode to whether*/
  566. {
  567.     if (whether == fullScreen) return;
  568.  
  569.     fullScreen = whether;
  570.  
  571. #ifdef GRAPHICS
  572.     if (fullScreen)
  573.     {
  574.     fullscrn();
  575.     }
  576.     else
  577.     {
  578.     endfullscrn();
  579.     }
  580. #endif
  581. }
  582.  
  583. void MakeOrthoXform()
  584. /*Makes an orthographic transformation based on the current state.*/
  585. {
  586.     if (drawingMode == DRAW_SCREEN)
  587.     {
  588. #ifdef GRAPHICS
  589.     mmode(MPROJECTION);
  590.     ortho2( 0.0,
  591.         (float) (CURSTATE . viewport[1] - CURSTATE . viewport[0]),
  592.         0.0,
  593.         (float) (CURSTATE . viewport[3] - CURSTATE . viewport[2]));
  594.     mmode(MVIEWING);
  595.     loadmatrix(Identity);
  596.  
  597.     translate((Coord) CURSTATE . translation[0],
  598.           (Coord) CURSTATE . translation[1], (Coord) 0.0);
  599. #endif
  600.     }
  601. }
  602.  
  603. void MakePickOrthoXform()
  604. /*Makes an orthographic transformation based on the current state.*/
  605. {
  606. #ifdef GRAPHICS
  607.     ortho2( 0.0,
  608.         (float) (CURSTATE . viewport[1] - CURSTATE . viewport[0]),
  609.         0.0,
  610.         (float) (CURSTATE . viewport[3] - CURSTATE . viewport[2]));
  611. #endif
  612. }
  613.  
  614. #ifdef PROTO
  615. void SetClipRect(int left, int right, int bottom, int top)
  616. #else
  617. void SetClipRect(left, right, bottom, top)
  618. int left, right, bottom, top;
  619. #endif
  620. /*Sets the current clipping rectangle to left, right, bottom, top*/
  621. {
  622.     int sl, sr, sb, st;
  623.  
  624.     EchoDraw("SetClipRect");
  625.  
  626.     /*Save the current state*/
  627.     PushDrawingState();
  628.  
  629.     left += CURSTATE . translation[0];
  630.     right += CURSTATE . translation[0];
  631.     bottom += CURSTATE . translation[1];
  632.     top += CURSTATE . translation[1];
  633.  
  634.     sl = CURSTATE . screenMask[0];
  635.     sr = CURSTATE . screenMask[1];
  636.     sb = CURSTATE . screenMask[2];
  637.     st = CURSTATE . screenMask[3];
  638.  
  639.     if (left > sl) sl = MIN(left, sr);
  640.     if (right < sr) sr = MAX(right, sl);
  641.     if (bottom > sb) sb = MIN(bottom, st);
  642.     if (top < st) st = MAX(top, sb);
  643.  
  644.     CURSTATE . screenMask[0] = sl;
  645.     CURSTATE . screenMask[1] = sr;
  646.     CURSTATE . screenMask[2] = sb;
  647.     CURSTATE . screenMask[3] = st;
  648.  
  649.     if (drawingMode == DRAW_SCREEN)
  650.     {
  651. #ifdef GRAPHICS
  652.     scrmask(sl, sr - 1, sb, st - 1);
  653. #endif
  654.     }
  655.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  656.     {
  657.         fprintf(psFile,
  658. "resetclip newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath clip newpath\n",
  659.         sl, st, sr, st, sr, sb, sl, sb);
  660.     }
  661. }
  662.  
  663. void RestoreClipRect()
  664. /*Restores the clipping rectangle to what it was before*/
  665. {
  666.     PopDrawingState();
  667.     EchoDraw("RestoreClipRect");
  668. }
  669.  
  670. void CurOffset(x, y)
  671. int *x, *y;
  672. /*Returns the current offset of the internal mouse coords from global*/
  673. {
  674.     int ox, oy;
  675.  
  676.     *x = CURSTATE . origin[0] + CURSTATE . translation[0];
  677.     *y = CURSTATE . origin[1] + CURSTATE . translation[1];
  678. }
  679.  
  680. void UD(void)
  681. /*Updated drawing according to belated DrawMe's*/
  682. {
  683. #ifdef GRAPHICS
  684.     if (drawMouse)
  685.     {
  686.     IdleAllWindows();
  687.     drawMouse = false;
  688.     }
  689. #endif
  690. }
  691.  
  692. void UpdateDrawing(void)
  693. /*Updates drawing according to belated DrawMe's*/
  694. {
  695.    UD();
  696. }
  697.  
  698. #ifdef GRAPHICS
  699. void DrawObj2(origObj, obj)
  700. ObjPtr origObj, obj;
  701. /*Draws origObj according to method in obj*/
  702. {
  703.     FuncTyp DrawFunction;            /*Method*/
  704.  
  705.     if (obj)
  706.     {
  707.     DrawObj2(origObj, ClassOf(obj));
  708.     DrawFunction = Get1Method(obj, DRAW);
  709.     if (DrawFunction)
  710.     {
  711.         (*DrawFunction)(origObj);
  712.     }
  713.     }
  714. }
  715. #endif
  716.  
  717. void DrawObject(obj)
  718. ObjPtr obj;
  719. /*Draws obj.*/
  720. {
  721. #ifdef GRAPHICS
  722.     ObjPtr picState;
  723.  
  724.     if (GetPredicate(obj, INHIBITDRAWING))
  725.     {
  726.     return;
  727.     }
  728.  
  729.     if (GetPredicate(obj, HIDDEN))
  730.     {
  731.     return;
  732.     }
  733.  
  734.     if (GetPredicate(obj, MULTIDRAW))
  735.     {
  736.     DrawObj2(obj, obj);
  737.     }
  738.     else
  739.     {
  740.     FuncTyp DrawFunction;            /*Method*/
  741.  
  742.     DrawFunction = GetMethod(obj, DRAW);
  743.     if (DrawFunction)
  744.     {
  745.         (*DrawFunction)(obj);
  746.     }
  747.     }
  748. #endif
  749. }
  750.  
  751. void ClipToMe(object)
  752. ObjPtr object;
  753. /*Sets the clipping rectangle to object*/
  754. {
  755.     int l, r, b, t;
  756.  
  757.     Get2DIntBounds(object, &l, &r, &b, &t);
  758.  
  759.     SetClipRect(l, r, b, t);
  760. }
  761.  
  762. #ifdef INTERACTIVE
  763. ObjPtr PressObject(obj, x, y, flags)
  764. ObjPtr obj;
  765. int x, y;
  766. long flags;
  767. /*Presses in obj at x, y*/
  768. {
  769.     FuncTyp PressFunction;
  770.     PressFunction = GetMethod(obj, PRESS);
  771.     if (PressFunction)
  772.     {
  773.     return (*PressFunction)(obj, x, y, flags);
  774.     }
  775.     else
  776.     {
  777.     return ObjFalse;
  778.     }
  779. }
  780. #endif
  781.  
  782. ObjPtr DropObjects(obj, dropObj, x, y)
  783. ObjPtr obj, dropObj;
  784. int x, y;
  785. /*Drops objects in list dropObj in obj at x, y*/
  786. {
  787.     FuncTyp method;
  788.     method = GetMethod(obj, DROPOBJECTS);
  789.     if (method)
  790.     {
  791.     return (*method)(obj, dropObj, x, y);
  792.     }
  793.     else
  794.     {
  795.     return ObjFalse;
  796.     }
  797. }
  798.  
  799. #ifdef PROTO
  800. ObjPtr KeyDownObject(ObjPtr obj, int key, long flags)
  801. #else
  802. ObjPtr KeyDownObject(obj, key, flags)
  803. ObjPtr obj;
  804. int key;
  805. long flags;
  806. #endif
  807. /*Does a keydown in obj*/
  808. {
  809.     FuncTyp method;
  810.     method = GetMethod(obj, KEYDOWN);
  811.     if (method)
  812.     {
  813.     return (*method)(obj, key, flags);
  814.     }
  815.     else
  816.     {
  817.     return ObjFalse;
  818.     }
  819. }
  820.  
  821. void FrameUIRect(left, right, bottom, top, uiColor)
  822. int left, right, bottom, top, uiColor;
  823. /*Frames a user interface rectangle*/
  824. {
  825. #ifdef GRAPHICS
  826.     SetUIColor(uiColor);
  827.     FrameRect(left, right, bottom, top);
  828. #endif
  829. }
  830.  
  831. void FrameRect(left, right, bottom, top)
  832. int left, right, bottom, top;
  833. /*Frames a rectangle*/
  834. {
  835. #ifdef GRAPHICS
  836.  
  837.     if (drawingMode == DRAW_SCREEN)
  838.     {
  839. #ifdef V3FISBUGGED
  840.     move2(left + 0.5, top - 0.5);
  841.     draw2(left + 0.5, bottom + 0.5);
  842.     draw2(right - 0.5, bottom + 0.5);
  843.     draw2(right - 0.5, top - 0.5);
  844.     draw2(left + 0.5, top - 0.5);
  845. #else
  846.     float v[5][2];
  847.     v[0][0] = left + 0.5;
  848.     v[0][1] = top - 0.5;
  849.     v[1][0] = left + 0.5;
  850.     v[1][1] = bottom + 0.5;
  851.     v[2][0] = right - 0.5;
  852.     v[2][1] = bottom + 0.5;
  853.     v[3][0] = right - 0.5;
  854.     v[3][1] = top - 0.5;
  855.     v[4][0] = left + 0.5;
  856.     v[4][1] = top - 0.5;
  857.     bgnline();
  858.     v2f(v[0]);
  859.     v2f(v[1]);
  860.     v2f(v[2]);
  861.     v2f(v[3]);
  862.     v2f(v[4]);
  863.     endline();
  864. #endif
  865.     }
  866.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  867.     {
  868.     fprintf(psFile, "%f setgray\n", PSColor());
  869.         fprintf(psFile, "%d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath stroke\n",
  870.             left, top, right, top, right, bottom, left, bottom); 
  871.     }
  872. #endif
  873. }
  874.  
  875. void FillUIRect(left, right, bottom, top, uiColor)
  876. int left, right, bottom, top, uiColor;
  877. /*Fills a user interface rectangle*/
  878. {
  879. #ifdef GRAPHICS
  880.  
  881.     SetUIColor(uiColor);
  882.     FillRect(left, right, bottom, top);
  883. #endif
  884. }
  885.  
  886. void FillRect(left, right, bottom, top)
  887. int left, right, bottom, top;
  888. /*Fills a rectangle*/
  889. {
  890. #ifdef GRAPHICS
  891.     FillIntQuad(left, bottom,
  892.          (right), bottom,
  893.          (right), (top),
  894.          left, (top));
  895. #endif
  896. }
  897.  
  898. void FillUIGauzeDisc(x, y, radius, uiColor)
  899. int x, y, radius, uiColor;
  900. /*Fills a disc in uiColor with gauze pattern*/
  901. {
  902. #ifdef GRAPHICS
  903.     SetUIColor(uiColor);
  904.     BeginTranslucent();
  905.     circfi(x, y, radius);
  906.     EndTranslucent();
  907. #endif
  908. }
  909.  
  910. void FillUIDisc(x, y, radius, uiColor)
  911. int x, y, radius, uiColor;
  912. /*Fills a disc in uiColor*/
  913. {
  914. #ifdef GRAPHICS
  915.     SetUIColor(uiColor);
  916.     if (drawingMode == DRAW_SCREEN)
  917.     {
  918.         circfi(x, y, radius);
  919.     }
  920.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  921.     {
  922.     fprintf(psFile, "%f setgray\n", PSColor());
  923.         fprintf(psFile, "newpath %d %d %d 0 360 arc fill\n", x, y, radius);
  924.     }
  925. #endif
  926. }
  927.  
  928. void FillTri(x1, y1, x2, y2, x3, y3)
  929. int x1, y1, x2, y2, x3, y3;
  930. /*Fills a triangle*/
  931. {
  932. #ifdef GRAPHICS
  933.  
  934.     if (drawingMode == DRAW_SCREEN)
  935.     {
  936.     float v[3][2];
  937.     v[0][0] = x1;
  938.     v[0][1] = y1;
  939.     v[1][0] = x2;
  940.     v[1][1] = y2;
  941.     v[2][0] = x3;
  942.     v[2][1] = y3;
  943.     bgnpolygon();
  944.     v2f(v[0]);
  945.     v2f(v[1]);
  946.     v2f(v[2]);
  947.     endpolygon();
  948.     }
  949.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  950.     {
  951.     fprintf(psFile, "%f setgray\n", PSColor());
  952.         fprintf(psFile, "%d %d moveto %d %d lineto %d %d lineto closepath fill\n",
  953.             x1, y1, x2, y2, x3, y3); 
  954.     }
  955. #endif
  956. }
  957.  
  958. void FillUITri(x1, y1, x2, y2, x3, y3, uiColor)
  959. int x1, y1, x2, y2, x3, y3, uiColor;
  960. /*Fills a triangle in uiColor*/ 
  961. #ifdef GRAPHICS 
  962.     SetUIColor(uiColor);
  963.     FillTri(x1, y1, x2, y2, x3, y3);
  964. #endif
  965. }
  966.  
  967. void FillUIGauzeRect(left, right, bottom, top, uiColor)
  968. int left, right, bottom, top, uiColor;
  969. /*Fills a user interface rectangle as if it were gauze*/
  970. {
  971. #ifdef GRAPHICS
  972.  
  973.     SetUIColor(uiColor);
  974.     BeginTranslucent();
  975.     FillIntQuad(left, (top),
  976.          left, bottom,
  977.          (right), bottom,
  978.          (right), (top));
  979.     EndTranslucent();
  980. #endif
  981. }
  982.  
  983. void DrawUILine(x1, y1, x2, y2, uiColor)
  984. int x1, y1, x2, y2, uiColor;
  985. {
  986. #ifdef GRAPHICS
  987.  
  988.     SetUIColor(uiColor);
  989.     DrawLine(x1, y1, x2, y2);
  990. #endif
  991. }
  992.  
  993. void DrawLine(x1, y1, x2, y2)
  994. int x1, y1, x2, y2;
  995. {
  996. #ifdef GRAPHICS
  997.     if (drawingMode == DRAW_SCREEN)
  998.     {
  999. #ifdef V3FISBUGGED
  1000.     move2(x1 + 0.5, y1 + 0.5);
  1001.     draw2(x2 + 0.5, y2 + 0.5);
  1002. #else
  1003.     float v[2][2];
  1004.     v[0][0] = x1 + 0.5;
  1005.     v[0][1] = y1 + 0.5;
  1006.     v[1][0] = x2 + 0.5;
  1007.     v[1][1] = y2 + 0.5;
  1008.     bgnline();
  1009.     v2f(v[0]);
  1010.     v2f(v[1]);
  1011.     endline();
  1012. #endif
  1013.     }
  1014.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  1015.     {
  1016.     fprintf(psFile, "%f setgray\n", PSColor());
  1017.         fprintf(psFile, "%d %d moveto %d %d lineto stroke\n",
  1018.             x1, y1, x2, y2);
  1019.     }
  1020. #endif
  1021. }
  1022.  
  1023. void FillUIWedge(x, y, radius, start, end, uiColor)
  1024. int x, y, radius, start, end, uiColor;
  1025. /*Fills a solid wege at x, y with radius from start to end degrees*/
  1026. {
  1027. #ifdef GRAPHICS
  1028.     SetUIColor(uiColor);
  1029.     if (drawingMode == DRAW_SCREEN)
  1030.     {
  1031.     arcfi(x, y, radius, start * 10, end * 10);
  1032.     }
  1033.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  1034.     {
  1035.     fprintf(psFile, "%f setgray\n", PSColor());
  1036.     fprintf(psFile, "newpath %d %d moveto %d %d %d %d %d arc closepath fill\n", 
  1037.         x, y, x, y, radius, start, end);
  1038.     }
  1039. #endif
  1040. }
  1041.  
  1042. void DrawArc(x, y, radius, start, end)
  1043. int x, y, radius, start, end;
  1044. /*Draws an arc in the current color.  start and end are in degrees.*/
  1045. {
  1046.     if (drawingMode == DRAW_SCREEN)
  1047.     {
  1048. #ifdef GRAPHICS
  1049.     arci(x, y, radius, start * 10, end * 10);
  1050. #endif
  1051.     }
  1052.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  1053.     {
  1054.     fprintf(psFile, "%f setgray\n", PSColor());
  1055.     fprintf(psFile, "newpath %d %d %d %d %d arc stroke\n", 
  1056.         x, y, radius, start, end);
  1057.     }
  1058. }
  1059.  
  1060. #ifdef PROTO
  1061. void FillSpaceRect(real x1, real y1, real z1,
  1062.            real x2, real y2, real z2,
  1063.            real x3, real y3, real z3,
  1064.            real x4, real y4, real z4,
  1065.            real nx, real ny, real nz)
  1066. #else
  1067. void FillSpaceRect( x1,  y1,  z1,
  1068.             x2,  y2,  z2,
  1069.             x3,  y3,  z3,
  1070.             x4,  y4,  z4,
  1071.             nx,  ny,  nz)
  1072. real x1; real y1; real z1;
  1073. real x2; real y2; real z2;
  1074. real x3; real y3; real z3;
  1075. real x4; real y4; real z4;
  1076. real nx; real ny; real nz;
  1077. #endif
  1078. /*Draws a rectangle in space around [xyz]1 through [xyz]4 using n[xyz]
  1079.   as normal.  If n[xyz] is 0, doesn't do a normal*/
  1080. {
  1081. #ifdef GRAPHICS
  1082.     float v[4][3];
  1083.     float n[3];
  1084.  
  1085.     v[0][0] = x1;
  1086.     v[0][1] = y1;
  1087.     v[0][2] = z1;
  1088.     v[1][0] = x2;
  1089.     v[1][1] = y2;
  1090.     v[1][2] = z2;
  1091.     v[2][0] = x3;
  1092.     v[2][1] = y3;
  1093.     v[2][2] = z3;
  1094.     v[3][0] = x4;
  1095.     v[3][1] = y4;
  1096.     v[3][2] = z4;
  1097.  
  1098.     if (nx != 0.0 || ny != 0.0 || nz != 0.0)
  1099.     {
  1100.     n[0] = nx;
  1101.     n[1] = ny;
  1102.     n[2] = nz;
  1103.     }
  1104.     bgnpolygon();
  1105.     N3F(n);
  1106.     v3f(v[0]);
  1107.     v3f(v[1]);
  1108.     v3f(v[2]);
  1109.     v3f(v[3]);
  1110.     endpolygon();
  1111. #endif
  1112. }
  1113.  
  1114. #ifdef PROTO
  1115. void FrameSpaceRect(real x1, real y1, real z1,
  1116.            real x2, real y2, real z2,
  1117.            real x3, real y3, real z3,
  1118.            real x4, real y4, real z4)
  1119. #else
  1120. void FrameSpaceRect( x1,  y1,  z1,
  1121.             x2,  y2,  z2,
  1122.             x3,  y3,  z3,
  1123.             x4,  y4,  z4)
  1124. real x1; real y1; real z1;
  1125. real x2; real y2; real z2;
  1126. real x3; real y3; real z3;
  1127. real x4; real y4; real z4;
  1128. #endif
  1129. /*Frames a rectangle in space around [xyz]1 through [xyz]4*/
  1130. {
  1131.     DrawSpaceLine(x1, y1, z1, x2, y2, z2);
  1132.     DrawSpaceLine(x2, y2, z2, x3, y3, z3);
  1133.     DrawSpaceLine(x3, y3, z3, x4, y4, z4);
  1134.     DrawSpaceLine(x4, y4, z4, x1, y1, z1);
  1135. }
  1136.  
  1137. #ifdef PROTO
  1138. void DrawSpaceLine(real x1, real y1, real z1, real x2, real y2, real z2)
  1139. #else
  1140. void DrawSpaceLine(x1, y1, z1, x1, y1, z1)
  1141. real x1; real y1; real z1;
  1142. real x2; real y2; real z2;
  1143. #endif
  1144. /*Draws a line in a space*/
  1145. {
  1146.     float v[2][3];
  1147. #ifdef GRAPHICS
  1148.  
  1149. #ifdef V3FISBUGGED
  1150.     move(x1, y1, z1);
  1151.     draw(x2, y2, z2);
  1152. #else
  1153.     /*Draws a line in a space*/
  1154.     v[0][0] = x1;
  1155.     v[0][1] = y1;
  1156.     v[0][2] = z1;
  1157.     v[1][0] = x2;
  1158.     v[1][1] = y2;
  1159.     v[1][2] = z2;
  1160.     bgnline();
  1161.     v3f(v[0]);
  1162.     v3f(v[1]);
  1163.     endline();
  1164. #endif
  1165. #endif
  1166. }
  1167.  
  1168. #ifdef PROTO
  1169. void DrawSpacePanelLine(real x1, real y1, real x2, real y2, real width, int arrow,
  1170.                 real arrowParams[4][2])
  1171. #else
  1172. void DrawSpacePanelLine(x1, y1, x2, y2, width, arrow, arrowParams)
  1173. real x1, y1, x2, y2, width;
  1174. int arrow;
  1175. real arrowParams[4][2];
  1176. #endif
  1177. /*Draws a space panel line*/
  1178. /* DIK need to make PostScript version */
  1179. {
  1180. #ifdef GRAPHICS
  1181.     if (x1 == y1 && x2 == y2)
  1182.     {
  1183.     /*Just a point*/
  1184.     long v[2];
  1185.  
  1186.     bgnpoint();
  1187.     v[0] = x1;
  1188.     v[1] = y1;
  1189.     v2i(v);
  1190.     endpoint();
  1191.     }
  1192.     else if (width <= 1 && arrow == AH_NO_ARROW)
  1193.     {
  1194.     /*Plain line*/
  1195.     long v[2][2];
  1196.  
  1197.     v[0][0] = x1;
  1198.     v[0][1] = y1;
  1199.     v[1][0] = x2;
  1200.     v[1][1] = y2;
  1201.     bgnline();
  1202.     v2i(v[0]);
  1203.     v2i(v[1]);
  1204.     endline();
  1205.     }
  1206.     else
  1207.     {
  1208.     /*Solid line*/
  1209.     real ax, ay, nx, ny, rr, mx, my;
  1210.     float v[10][2];
  1211.  
  1212.     /*Calculate the axial unit vector*/
  1213.     ax = x2 - x1;
  1214.     ay = y2 - y1;
  1215.     rr = 1.0 / sqrt(ax * ax + ay * ay);
  1216.     ax *= rr;
  1217.     ay *= rr;
  1218.  
  1219.     /*Now the normal unit vector*/
  1220.     nx = -ay;
  1221.     ny = ax;
  1222.  
  1223.     switch(arrow)
  1224.     {
  1225.         case AH_NO_ARROW:
  1226.         v[0][0] = x1 - nx * width * 0.5;
  1227.         v[0][1] = y1 - ny * width * 0.5; 
  1228.         v[1][0] = x2 - nx * width * 0.5;
  1229.         v[1][1] = y2 - ny * width * 0.5; 
  1230.         v[2][0] = x2 + nx * width * 0.5;
  1231.         v[2][1] = y2 + ny * width * 0.5; 
  1232.         v[3][0] = x1 + nx * width * 0.5;
  1233.         v[3][1] = y1 + ny * width * 0.5; 
  1234.             bgnpolygon();
  1235.         v2f(v[0]);
  1236.         v2f(v[1]);
  1237.         v2f(v[2]);
  1238.         v2f(v[3]);
  1239.         endpolygon();
  1240.         break;
  1241.         case AH_AT_END:
  1242.  
  1243.         /*Arrow base*/
  1244.         v[0][0] = x1;
  1245.         v[0][1] = y1;
  1246.  
  1247.         /*Down to fletching*/
  1248.         v[1][0] = x1 + ax * width * arrowParams[0][0] -
  1249.                  nx * width * arrowParams[0][1];
  1250.         v[1][1] = y1 + ay * width * arrowParams[0][0] -
  1251.                  ny * width * arrowParams[0][1];
  1252.  
  1253.         /*Over to shaft*/
  1254.         v[2][0] = x2 + ax * width * arrowParams[1][0] -
  1255.                  nx * width * arrowParams[1][1];
  1256.         v[2][1] = y2 + ay * width * arrowParams[1][0] -
  1257.                  ny * width * arrowParams[1][1];
  1258.  
  1259.         /*To first arrowhead tip*/
  1260.         v[3][0] = x2 + ax * width * arrowParams[2][0] -
  1261.                  nx * width * arrowParams[2][1];
  1262.         v[3][1] = y2 + ay * width * arrowParams[2][0] -
  1263.                  ny * width * arrowParams[2][1];
  1264.  
  1265.         /*To second arrowhead tip*/
  1266.         v[4][0] = x2 + ax * width * arrowParams[3][0] -
  1267.                  nx * width * arrowParams[3][1];
  1268.         v[4][1] = y2 + ay * width * arrowParams[3][0] -
  1269.                  ny * width * arrowParams[3][1];
  1270.  
  1271.         /*To end of arrow*/
  1272.         v[5][0] = x2;
  1273.         v[5][1] = y2;
  1274.  
  1275.         /*Up to second arrowhead tip*/
  1276.         v[6][0] = x2 + ax * width * arrowParams[3][0] +
  1277.                  nx * width * arrowParams[3][1];
  1278.         v[6][1] = y2 + ay * width * arrowParams[3][0] +
  1279.                  ny * width * arrowParams[3][1];
  1280.  
  1281.         /*Back to first arrowhead tip*/
  1282.         v[7][0] = x2 + ax * width * arrowParams[2][0] +
  1283.                  nx * width * arrowParams[2][1];
  1284.         v[7][1] = y2 + ay * width * arrowParams[2][0] +
  1285.                  ny * width * arrowParams[2][1];
  1286.  
  1287.         /*Down to shaft*/
  1288.         v[8][0] = x2 + ax * width * arrowParams[1][0] +
  1289.                  nx * width * arrowParams[1][1];
  1290.         v[8][1] = y2 + ay * width * arrowParams[1][0] +
  1291.                  ny * width * arrowParams[1][1];
  1292.  
  1293.         /*Back to fletching*/
  1294.         v[9][0] = x1 + ax * width * arrowParams[0][0] +
  1295.                  nx * width * arrowParams[0][1];
  1296.         v[9][1] = y1 + ay * width * arrowParams[0][0] +
  1297.                  ny * width * arrowParams[0][1];
  1298.  
  1299.             bgnpolygon();
  1300.         v2f(v[0]);
  1301.         v2f(v[1]);
  1302.         v2f(v[2]);
  1303.         v2f(v[3]);
  1304.         v2f(v[4]);
  1305.         v2f(v[5]);
  1306.         v2f(v[6]);
  1307.         v2f(v[7]);
  1308.         v2f(v[8]);
  1309.         v2f(v[9]);
  1310.         endpolygon();
  1311.         break;
  1312.         case AH_AT_START:
  1313.  
  1314.         /*Arrow base*/
  1315.         v[0][0] = x2;
  1316.         v[0][1] = y2;
  1317.  
  1318.         /*Down to fletching*/
  1319.         v[1][0] = x2 - ax * width * arrowParams[0][0] +
  1320.                  nx * width * arrowParams[0][1];
  1321.         v[1][1] = y2 - ay * width * arrowParams[0][0] +
  1322.                  ny * width * arrowParams[0][1];
  1323.  
  1324.         /*Over to shaft*/
  1325.         v[2][0] = x1 - ax * width * arrowParams[1][0] +
  1326.                  nx * width * arrowParams[1][1];
  1327.         v[2][1] = y1 - ay * width * arrowParams[1][0] +
  1328.                  ny * width * arrowParams[1][1];
  1329.  
  1330.         /*To first arrowhead tip*/
  1331.         v[3][0] = x1 - ax * width * arrowParams[2][0] +
  1332.                  nx * width * arrowParams[2][1];
  1333.         v[3][1] = y1 - ay * width * arrowParams[2][0] +
  1334.                  ny * width * arrowParams[2][1];
  1335.  
  1336.         /*To second arrowhead tip*/
  1337.         v[4][0] = x1 - ax * width * arrowParams[3][0] +
  1338.                  nx * width * arrowParams[3][1];
  1339.         v[4][1] = y1 - ay * width * arrowParams[3][0] +
  1340.                  ny * width * arrowParams[3][1];
  1341.  
  1342.         /*To end of arrow*/
  1343.         v[5][0] = x1;
  1344.         v[5][1] = y1;
  1345.  
  1346.         /*Up to second arrowhead tip*/
  1347.         v[6][0] = x1 - ax * width * arrowParams[3][0] -
  1348.                  nx * width * arrowParams[3][1];
  1349.         v[6][1] = y1 - ay * width * arrowParams[3][0] -
  1350.                  ny * width * arrowParams[3][1];
  1351.  
  1352.         /*Back to first arrowhead tip*/
  1353.         v[7][0] = x1 - ax * width * arrowParams[2][0] -
  1354.                  nx * width * arrowParams[2][1];
  1355.         v[7][1] = y1 - ay * width * arrowParams[2][0] -
  1356.                  ny * width * arrowParams[2][1];
  1357.  
  1358.         /*Down to shaft*/
  1359.         v[8][0] = x1 - ax * width * arrowParams[1][0] -
  1360.                  nx * width * arrowParams[1][1];
  1361.         v[8][1] = y1 - ay * width * arrowParams[1][0] -
  1362.                  ny * width * arrowParams[1][1];
  1363.  
  1364.         /*Back to fletching*/
  1365.         v[9][0] = x2 - ax * width * arrowParams[0][0] -
  1366.                  nx * width * arrowParams[0][1];
  1367.         v[9][1] = y2 - ay * width * arrowParams[0][0] -
  1368.                  ny * width * arrowParams[0][1];
  1369.  
  1370.             bgnpolygon();
  1371.         v2f(v[0]);
  1372.         v2f(v[1]);
  1373.         v2f(v[2]);
  1374.         v2f(v[3]);
  1375.         v2f(v[4]);
  1376.         v2f(v[5]);
  1377.         v2f(v[6]);
  1378.         v2f(v[7]);
  1379.         v2f(v[8]);
  1380.         v2f(v[9]);
  1381.         endpolygon();
  1382.         break;
  1383.  
  1384.         case AH_BOTH_ENDS:
  1385.         /*Calculate midpoints*/
  1386.         mx = (x1 + x2) * 0.5;
  1387.         my = (y1 + y2) * 0.5;
  1388.  
  1389.         /*Do at end first*/
  1390.  
  1391.         /*Arrow base*/
  1392.         v[0][0] = mx;
  1393.         v[0][1] = my;
  1394.  
  1395.         /*Down to fletching*/
  1396.         v[1][0] = mx + ax * width * arrowParams[0][0] -
  1397.                  nx * width * arrowParams[0][1];
  1398.         v[1][1] = my + ay * width * arrowParams[0][0] -
  1399.                  ny * width * arrowParams[0][1];
  1400.  
  1401.         /*Over to shaft*/
  1402.         v[2][0] = x2 + ax * width * arrowParams[1][0] -
  1403.                  nx * width * arrowParams[1][1];
  1404.         v[2][1] = y2 + ay * width * arrowParams[1][0] -
  1405.                  ny * width * arrowParams[1][1];
  1406.  
  1407.         /*To first arrowhead tip*/
  1408.         v[3][0] = x2 + ax * width * arrowParams[2][0] -
  1409.                  nx * width * arrowParams[2][1];
  1410.         v[3][1] = y2 + ay * width * arrowParams[2][0] -
  1411.                  ny * width * arrowParams[2][1];
  1412.  
  1413.         /*To second arrowhead tip*/
  1414.         v[4][0] = x2 + ax * width * arrowParams[3][0] -
  1415.                  nx * width * arrowParams[3][1];
  1416.         v[4][1] = y2 + ay * width * arrowParams[3][0] -
  1417.                  ny * width * arrowParams[3][1];
  1418.  
  1419.         /*To end of arrow*/
  1420.         v[5][0] = x2;
  1421.         v[5][1] = y2;
  1422.  
  1423.         /*Up to second arrowhead tip*/
  1424.         v[6][0] = x2 + ax * width * arrowParams[3][0] +
  1425.                  nx * width * arrowParams[3][1];
  1426.         v[6][1] = y2 + ay * width * arrowParams[3][0] +
  1427.                  ny * width * arrowParams[3][1];
  1428.  
  1429.         /*Back to first arrowhead tip*/
  1430.         v[7][0] = x2 + ax * width * arrowParams[2][0] +
  1431.                  nx * width * arrowParams[2][1];
  1432.         v[7][1] = y2 + ay * width * arrowParams[2][0] +
  1433.                  ny * width * arrowParams[2][1];
  1434.  
  1435.         /*Down to shaft*/
  1436.         v[8][0] = x2 + ax * width * arrowParams[1][0] +
  1437.                  nx * width * arrowParams[1][1];
  1438.         v[8][1] = y2 + ay * width * arrowParams[1][0] +
  1439.                  ny * width * arrowParams[1][1];
  1440.  
  1441.         /*Back to fletching*/
  1442.         v[9][0] = mx + ax * width * arrowParams[0][0] +
  1443.                  nx * width * arrowParams[0][1];
  1444.         v[9][1] = my + ay * width * arrowParams[0][0] +
  1445.                  ny * width * arrowParams[0][1];
  1446.  
  1447.             bgnpolygon();
  1448.         v2f(v[0]);
  1449.         v2f(v[1]);
  1450.         v2f(v[2]);
  1451.         v2f(v[3]);
  1452.         v2f(v[4]);
  1453.         v2f(v[5]);
  1454.         v2f(v[6]);
  1455.         v2f(v[7]);
  1456.         v2f(v[8]);
  1457.         v2f(v[9]);
  1458.         endpolygon();
  1459.  
  1460.         /*Now do at start*/
  1461.             bgnpolygon();
  1462.  
  1463.         /*Arrow base*/
  1464.         v[0][0] = mx;
  1465.         v[0][1] = my;
  1466.  
  1467.         /*Down to fletching*/
  1468.         v[1][0] = mx - ax * width * arrowParams[0][0] +
  1469.                  nx * width * arrowParams[0][1];
  1470.         v[1][1] = my - ay * width * arrowParams[0][0] +
  1471.                  ny * width * arrowParams[0][1];
  1472.  
  1473.         /*Over to shaft*/
  1474.         v[2][0] = x1 - ax * width * arrowParams[1][0] +
  1475.                  nx * width * arrowParams[1][1];
  1476.         v[2][1] = y1 - ay * width * arrowParams[1][0] +
  1477.                  ny * width * arrowParams[1][1];
  1478.  
  1479.         /*To first arrowhead tip*/
  1480.         v[3][0] = x1 - ax * width * arrowParams[2][0] +
  1481.                  nx * width * arrowParams[2][1];
  1482.         v[3][1] = y1 - ay * width * arrowParams[2][0] +
  1483.                  ny * width * arrowParams[2][1];
  1484.  
  1485.         /*To second arrowhead tip*/
  1486.         v[4][0] = x1 - ax * width * arrowParams[3][0] +
  1487.                  nx * width * arrowParams[3][1];
  1488.         v[4][1] = y1 - ay * width * arrowParams[3][0] +
  1489.                  ny * width * arrowParams[3][1];
  1490.  
  1491.         /*To end of arrow*/
  1492.         v[5][0] = x1;
  1493.         v[5][1] = y1;
  1494.  
  1495.         /*Up to second arrowhead tip*/
  1496.         v[6][0] = x1 - ax * width * arrowParams[3][0] -
  1497.                  nx * width * arrowParams[3][1];
  1498.         v[6][1] = y1 - ay * width * arrowParams[3][0] -
  1499.                  ny * width * arrowParams[3][1];
  1500.         
  1501.         /*Back to first arrowhead tip*/
  1502.         v[7][0] = x1 - ax * width * arrowParams[2][0] -
  1503.                  nx * width * arrowParams[2][1];
  1504.         v[7][1] = y1 - ay * width * arrowParams[2][0] -
  1505.                  ny * width * arrowParams[2][1];
  1506.         
  1507.         /*Down to shaft*/
  1508.         v[8][0] = x1 - ax * width * arrowParams[1][0] -
  1509.                  nx * width * arrowParams[1][1];
  1510.         v[8][1] = y1 - ay * width * arrowParams[1][0] -
  1511.                  ny * width * arrowParams[1][1];
  1512.  
  1513.         /*Back to fletching*/
  1514.         v[9][0] = mx - ax * width * arrowParams[0][0] -
  1515.                  nx * width * arrowParams[0][1];
  1516.         v[9][1] = my - ay * width * arrowParams[0][0] -
  1517.                  ny * width * arrowParams[0][1];
  1518.  
  1519.             bgnpolygon();
  1520.         v2f(v[0]);
  1521.         v2f(v[1]);
  1522.         v2f(v[2]);
  1523.         v2f(v[3]);
  1524.         v2f(v[4]);
  1525.         v2f(v[5]);
  1526.         v2f(v[6]);
  1527.         v2f(v[7]);
  1528.         v2f(v[8]);
  1529.         v2f(v[9]);
  1530.         endpolygon();
  1531.         break;
  1532.     }    
  1533.     }
  1534. #endif
  1535. }
  1536.  
  1537. void DrawVCursor(x, yt, yb)
  1538. int x, yt, yb;
  1539. /*Draws a vertical cursor*/
  1540. {
  1541. #ifdef GRAPHICS
  1542.     DrawUILine(x, yt, x, yb, UIRED);
  1543.     DrawUILine(x + 1, yt, x + 1, yb, UIBLACK);
  1544. #endif
  1545. }
  1546.  
  1547. #ifdef GRAPHICS
  1548. #ifdef FONTS4D
  1549. extern fmfonthandle currentFontHandle;
  1550. #endif
  1551. #endif
  1552.  
  1553. #ifdef PROTO
  1554. void DrawSpaceString(real x, real y, real z, char *s)
  1555. #else
  1556. void DrawSpaceString(x, y, z, s)
  1557. real x, y, z;
  1558. char *s;
  1559. #endif
  1560. /*Draws a string beginning at x, y, z in a space*/
  1561. /* DIK need PostScript version? */
  1562. {
  1563. #ifdef GRAPHICS
  1564.  
  1565.     cmov((Coord) x, (Coord) y, (Coord) z);
  1566. #ifdef FONTS4D
  1567.     if (currentFontHandle)
  1568.     {
  1569.         fmprstr(s);
  1570.     }
  1571.     else
  1572.     {
  1573.         charstr(s);
  1574.     }
  1575. #else
  1576.     charstr(s);
  1577. #endif
  1578. #endif
  1579. }
  1580.  
  1581. #ifdef PROTO
  1582. void DrawWFSphere(real x, real y, real z, real radius)
  1583. #else
  1584. void DrawWFSphere(x, y, z, radius)
  1585. real x, y, z, radius;
  1586. #endif
  1587. /*Draws a wire frame sphere*/
  1588. {
  1589. #ifdef GRAPHICS
  1590.     pushmatrix();
  1591.     translate(x, y, z);
  1592.     circ(0.0, 0.0, radius);
  1593.     translate(0.0, 0.0, radius * SQ22);
  1594.     circ(0.0, 0.0, radius * SQ22);
  1595.     translate(0.0, 0.0, -radius * 2.0 * SQ22);
  1596.     circ(0.0, 0.0, radius * SQ22);
  1597.     translate(0.0, 0.0, radius * SQ22);
  1598.     rotate(900, 'y');
  1599.     circ(0.0, 0.0, radius);
  1600.     rotate(450, 'x');
  1601.     circ(0.0, 0.0, radius);
  1602.     rotate(450, 'x');
  1603.     circ(0.0, 0.0, radius);
  1604.     rotate(450, 'x');
  1605.     circ(0.0, 0.0, radius);
  1606.     popmatrix();
  1607. #endif
  1608. }
  1609.  
  1610. #ifdef PROTO
  1611. void FillRealQuad(real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4)
  1612. #else
  1613. void FillRealQuad(x1, y1, x2, y2, x3, y3, x4, y4)
  1614. real x1, y1, x2, y2, x3, y3, x4, y4;
  1615. #endif
  1616. /*Fills a quadrilateral given real coordinates*/
  1617. {
  1618. #ifdef GRAPHICS
  1619.     if (drawingMode == DRAW_SCREEN)
  1620.     {
  1621.     float v[4][2];
  1622.     v[0][0] = x1;
  1623.     v[0][1] = y1;
  1624.     v[1][0] = x2;
  1625.     v[1][1] = y2;
  1626.     v[2][0] = x3;
  1627.     v[2][1] = y3;
  1628.     v[3][0] = x4;
  1629.     v[3][1] = y4;
  1630.     bgnpolygon();
  1631.     v2f(v[0]);
  1632.     v2f(v[1]);
  1633.     v2f(v[2]);
  1634.     v2f(v[3]);
  1635.     endpolygon();
  1636.     }
  1637.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  1638.     {
  1639.     fprintf(psFile, "%f setgray\n", PSColor());
  1640.         fprintf(psFile, "%g %g moveto %g %g lineto %g %g lineto %g %g lineto closepath fill\n",
  1641.             x1, y1, x2, y2, x3, y3, x4, y4); 
  1642.     }
  1643. #endif
  1644. }
  1645.  
  1646. #ifdef PROTO
  1647. void FillIntQuad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
  1648. #else
  1649. void FillIntQuad(x1, y1, x2, y2, x3, y3, x4, y4)
  1650. int x1, y1, x2, y2, x3, y3, x4, y4;
  1651. #endif
  1652. /*Fills a quadrilateral given real coordinates*/
  1653. {
  1654. #ifdef GRAPHICS
  1655.     if (drawingMode == DRAW_SCREEN)
  1656.     {
  1657.     long v[4][2];
  1658.     v[0][0] = x1;
  1659.     v[0][1] = y1;
  1660.     v[1][0] = x2;
  1661.     v[1][1] = y2;
  1662.     v[2][0] = x3;
  1663.     v[2][1] = y3;
  1664.     v[3][0] = x4;
  1665.     v[3][1] = y4;
  1666.     bgnpolygon();
  1667.     v2i(v[0]);
  1668.     v2i(v[1]);
  1669.     v2i(v[2]);
  1670.     v2i(v[3]);
  1671.     endpolygon();
  1672.     }
  1673.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  1674.     {
  1675.     fprintf(psFile, "%f setgray\n", PSColor());
  1676.         fprintf(psFile, "%d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath fill\n",
  1677.             x1, y1, x2, y2, x3, y3, x4, y4); 
  1678.     }
  1679. #endif
  1680. }
  1681.  
  1682. #ifdef PROTO
  1683. void FillRealQuint(real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4, real x5, real y5)
  1684. #else
  1685. void FillRealQuint(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5)
  1686. real x1, y1, x2, y2, x3, y3, x4, y4, x5, y5;
  1687. #endif
  1688. /*Fills a quintalateral given real coordinates*/
  1689. {
  1690. #ifdef GRAPHICS
  1691.     if (drawingMode == DRAW_SCREEN)
  1692.     {
  1693.     float v[5][2];
  1694.     v[0][0] = x1;
  1695.     v[0][1] = y1;
  1696.     v[1][0] = x2;
  1697.     v[1][1] = y2;
  1698.     v[2][0] = x3;
  1699.     v[2][1] = y3;
  1700.     v[3][0] = x4;
  1701.     v[3][1] = y4;
  1702.     v[4][0] = x5;
  1703.     v[4][1] = y5;
  1704.     bgnpolygon();
  1705.     v2f(v[0]);
  1706.     v2f(v[1]);
  1707.     v2f(v[2]);
  1708.     v2f(v[3]);
  1709.     v2f(v[4]);
  1710.     endpolygon();
  1711.     }
  1712.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  1713.     {
  1714.     fprintf(psFile, "%f setgray\n", PSColor());
  1715.         fprintf(psFile, "%g %g moveto %g %g lineto %g %g lineto %g %g lineto %g %g lineto closepath fill\n",
  1716.             x1, y1, x2, y2, x3, y3, x4, y4, x5, y5); 
  1717.     }
  1718. #endif
  1719. }
  1720.  
  1721. #ifdef PROTO
  1722. void FillRealHex(real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4, real x5, real y5, real x6, real y6)
  1723. #else
  1724. void FillRealHex(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6)
  1725. real x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6;
  1726. #endif
  1727. /*Fills a hexalateral given real coordinates*/
  1728. {
  1729. #ifdef GRAPHICS
  1730.     if (drawingMode == DRAW_SCREEN)
  1731.     {
  1732.     float v[6][2];
  1733.     v[0][0] = x1;
  1734.     v[0][1] = y1;
  1735.     v[1][0] = x2;
  1736.     v[1][1] = y2;
  1737.     v[2][0] = x3;
  1738.     v[2][1] = y3;
  1739.     v[3][0] = x4;
  1740.     v[3][1] = y4;
  1741.     v[4][0] = x5;
  1742.     v[4][1] = y5;
  1743.     v[5][0] = x6;
  1744.     v[5][1] = y6;
  1745.     bgnpolygon();
  1746.     v2f(v[0]);
  1747.     v2f(v[1]);
  1748.     v2f(v[2]);
  1749.     v2f(v[3]);
  1750.     v2f(v[4]);
  1751.     v2f(v[5]);
  1752.     endpolygon();
  1753.     }
  1754.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  1755.     {
  1756.     fprintf(psFile, "%f setgray\n", PSColor());
  1757.         fprintf(psFile, "%g %g moveto %g %g lineto %g %g lineto %g %g lineto %g %g lineto %g %g lineto closepath fill\n",
  1758.             x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6); 
  1759.     }
  1760. #endif
  1761. }
  1762.  
  1763. #ifdef PROTO
  1764. void FillRealRect(real left, real right, real bottom, real top)
  1765. #else
  1766. void FillRealRect(left, right, bottom, top)
  1767. real left, right, bottom, top;
  1768. #endif
  1769. /*Fills a rectangle, taking real coordinates*/
  1770. {
  1771. #ifdef GRAPHICS
  1772.     FillRealQuad(left, top, left, bottom, right, bottom, right, top);
  1773. #endif
  1774. }
  1775.  
  1776.  
  1777. #ifdef PROTO
  1778. void FrameRealWideRect(real left, real right, real bottom, real top, real width)
  1779. #else
  1780. void FrameRealWideRect(left, right, bottom, top, width)
  1781. real left, right, bottom, top, width;
  1782. #endif
  1783. /*Frames a wide rectangle taking real variables*/
  1784. {
  1785. #ifdef GRAPHICS
  1786.     FillRealRect(left, right, top - width, top);
  1787.     FillRealRect(left, right, bottom, bottom + width);
  1788.     FillRealRect(left, left + width, bottom, top);
  1789.     FillRealRect(right - width, right, bottom, top);
  1790. #endif
  1791. }
  1792.  
  1793. #ifdef PROTO
  1794. void FrameWideRect(int left, int right, int bottom, int top, int width)
  1795. #else
  1796. void FrameWideRect(left, right, bottom, top, width)
  1797. int left, right, bottom, top, width;
  1798. #endif
  1799. /*Frames a wide rectangle*/
  1800. {
  1801. #ifdef GRAPHICS
  1802.     FillRect(left, right, top - width + 1, top);
  1803.     FillRect(left, right, bottom, bottom + width - 1);
  1804.     FillRect(left, left + width - 1, bottom, top);
  1805.     FillRect(right - width + 1, right, bottom, top);
  1806. #endif
  1807. }
  1808.  
  1809. #ifdef PROTO
  1810. void FrameUIWideRect(int left, int right, int bottom, int top, int width, int color)
  1811. #else
  1812. void FrameUIWideRect(left, right, bottom, top, width, color)
  1813. int left, right, bottom, top, width, color;
  1814. #endif
  1815. /*Frames a wide rectangle in UI color*/
  1816. {
  1817. #ifdef GRAPHICS
  1818.     SetUIColor(color);
  1819.     FrameWideRect(left, right, bottom, top, width);
  1820. #endif
  1821. }
  1822.  
  1823. #ifdef PROTO
  1824. void DrawHandle(int x, int y)
  1825. #else
  1826. void DrawHandle(x, y)
  1827. int x, y;
  1828. #endif
  1829. /* Draws a handle at x,y */
  1830. {
  1831. #ifdef GRAPHICS
  1832.     FillUIRect(x - HANDLESIZE/2, x + HANDLESIZE / 2,
  1833.         y - HANDLESIZE/2, y + HANDLESIZE/2, OUTSIDEFRAMECOLOR);
  1834.     FillUIRect(x - HANDLESIZE/2 + OUTSIDEFRAMEWEIGHT,
  1835.         x + HANDLESIZE/2 - OUTSIDEFRAMEWEIGHT,
  1836.         y - HANDLESIZE/2 + OUTSIDEFRAMEWEIGHT,
  1837.         y + HANDLESIZE/2 - OUTSIDEFRAMEWEIGHT, INSIDEFRAMECOLOR);
  1838. #endif
  1839. }
  1840.  
  1841. #ifdef PROTO
  1842. Bool PointInHandle(int pointX, int pointY, int handleX, int handleY)
  1843. #else
  1844. Bool PointInHandle(pointX, pointY, handleX, handleY)
  1845. int pointX; int pointY; int handleX; int handleY;
  1846. #endif
  1847. /*Returns true if a point is inside a handle*/
  1848. {
  1849. #ifdef INTERACTIVE
  1850.     return (pointX >= handleX - HANDLESIZE / 2 &&
  1851.         pointX <= handleX + HANDLESIZE / 2 &&
  1852.         pointY >= handleY - HANDLESIZE / 2 &&
  1853.         pointY <= handleY + HANDLESIZE / 2) ? true : false;
  1854. #endif
  1855. }
  1856.  
  1857. #ifdef PROTO
  1858. void DrawRaisedEdge(int left, int right, int bottom, int top)
  1859. #else
  1860. void DrawRaisedEdge(left, right, bottom, top)
  1861. int left; int right; int bottom; int top;
  1862. #endif
  1863. /* draws a rectangular raised edge (JEL) */
  1864. {
  1865. #ifdef GRAPHICS
  1866.     /* bottom */
  1867.     SetUIColor(UIBOTTOMEDGE);
  1868.     FillIntQuad( left, bottom,
  1869.          right, bottom,
  1870.          right - EDGE, bottom + EDGE,
  1871.          left + EDGE, bottom + EDGE);
  1872.  
  1873.     /* left */
  1874.     SetUIColor(UILEFTEDGE);
  1875.     FillIntQuad( left,  bottom,
  1876.          left + EDGE, bottom + EDGE,
  1877.          left + EDGE, top - EDGE,
  1878.          left, top);
  1879.  
  1880.     /* right */
  1881.     SetUIColor(UIRIGHTEDGE);
  1882.     FillIntQuad( right - EDGE, bottom + EDGE,
  1883.          right, bottom,
  1884.          right, top,
  1885.          right - EDGE, top - EDGE);
  1886.  
  1887.     /* top */
  1888.     SetUIColor(UITOPEDGE);
  1889.     FillIntQuad( left + EDGE, top - EDGE,
  1890.          right - EDGE, top - EDGE,
  1891.          right, top,
  1892.          left, top);
  1893.     return;
  1894. #endif
  1895. }
  1896.  
  1897. #ifdef PROTO
  1898. void DrawSunkenEdge(int left, int right, int bottom, int top)
  1899. #else
  1900. void DrawSunkenEdge(left, right, bottom, top)
  1901. int left; int right; int bottom; int top;
  1902. #endif
  1903. /* draws a rectanglar sunken edge (JEL) 
  1904.    Fixed to be in CCW order (EMP) */
  1905. {
  1906. #ifdef GRAPHICS
  1907.     /* bottom */
  1908.     SetUIColor(UITOPEDGE);
  1909.     FillIntQuad( left, bottom,
  1910.          right, bottom,
  1911.          right - EDGE, bottom + EDGE,
  1912.          left + EDGE, bottom + EDGE);
  1913.  
  1914.     /* left */
  1915.     SetUIColor(UIRIGHTEDGE);
  1916.     FillIntQuad( left,  bottom,
  1917.          left + EDGE, bottom + EDGE,
  1918.          left + EDGE, top - EDGE,
  1919.          left, top);
  1920.  
  1921.     /* right */
  1922.     SetUIColor(UILEFTEDGE);
  1923.     FillIntQuad( right - EDGE, bottom + EDGE,
  1924.          right, bottom,
  1925.          right, top,
  1926.          right - EDGE, top - EDGE);
  1927.  
  1928.     /* top */
  1929.     SetUIColor(UIBOTTOMEDGE);
  1930.     FillIntQuad( left + EDGE, top - EDGE,
  1931.          right - EDGE, top - EDGE,
  1932.          right, top,
  1933.          left, top);
  1934.     return;
  1935. #endif
  1936. }
  1937.  
  1938. #ifdef PROTO
  1939. void DrawInsetRect(int left, int right, int bottom, int top)
  1940. #else
  1941. void DrawInsetRect(left, right, bottom, top)
  1942. int left; int right; int bottom; int top;
  1943. #endif
  1944. /* draws a rectangle filled with uiColor inset by EDGE from the given bounds */
  1945. {
  1946. #ifdef GRAPHICS
  1947.     FillRect(left + EDGE, right - EDGE, bottom + EDGE,
  1948.         top - EDGE);
  1949. #endif
  1950. }
  1951.  
  1952. #ifdef PROTO
  1953. void DrawInsetWashedRect(int left, int right, int bottom, int top, int washColor)
  1954. #else
  1955. void DrawInsetWashedRect(left, right, bottom, top, int washColor)
  1956. int left; int right; int bottom; int top; int washColor;
  1957. #endif
  1958. /* draws a rectangle filled with uiColor inset by EDGE from the given bounds */
  1959. {
  1960. #ifdef GRAPHICS
  1961.     FillUIRect(left + EDGE, right - EDGE, bottom + EDGE,
  1962.         top - EDGE, UIGRAY75);
  1963.     FillUIGauzeRect(left + EDGE, right - EDGE, bottom + EDGE,
  1964.         top - EDGE, washColor);
  1965. #endif
  1966. }
  1967.  
  1968. #ifdef PROTO
  1969. void DrawRaisedRect(int left, int right, int bottom, int top, int uiColor)
  1970. #else
  1971. void DrawRaisedRect(left, right, bottom, top, uiColor)
  1972. int left; int right; int bottom; int top; int uiColor;
  1973. #endif
  1974. /* draws a raised edge with filled rectangle inside */
  1975. {
  1976. #ifdef GRAPHICS
  1977.     SetUIColor(uiColor);
  1978.     DrawInsetRect(left, right, bottom, top);
  1979.     DrawRaisedEdge(left, right, bottom, top);
  1980. #endif
  1981. }
  1982.  
  1983. #ifdef PROTO
  1984. void DrawSunkenRect(int left, int right, int bottom, int top, int uiColor)
  1985. #else
  1986. void DrawSunkenRect(left, right, bottom, top, uiColor)
  1987. int left; int right; int bottom; int top; int uiColor;
  1988. #endif
  1989. /* draws a sunken edge with filled rectangle inside */
  1990. {
  1991. #ifdef GRAPHICS
  1992.     SetUIColor(uiColor);
  1993.     DrawInsetRect(left, right, bottom, top);
  1994.     DrawSunkenEdge(left, right, bottom, top);
  1995. #endif
  1996. }
  1997.  
  1998. void SetLineWidth(width)
  1999. int width;
  2000. /*Sets the line width to width*/
  2001. {
  2002. #ifdef GRAPHICS
  2003.     if (drawingMode == DRAW_SCREEN)
  2004.     {
  2005.         linewidth(width);
  2006.     }
  2007.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  2008.     {
  2009.         fprintf(psFile, "%d setlinewidth\n", width);
  2010.     }
  2011. #endif
  2012. }
  2013.  
  2014. void SetPointWidth(width)
  2015. int width;
  2016. /*Sets the line width to width*/
  2017. {
  2018. #ifdef GRAPHICS
  2019.     if (drawingMode == DRAW_SCREEN)
  2020.     {
  2021. #if MACHINE != RS6000
  2022.         pntsize((short) width);
  2023. #endif
  2024.     }
  2025. #endif
  2026. }
  2027.  
  2028. void    DrawMarkerSplat(left, right, bottom, top)
  2029. {
  2030.  
  2031. #ifdef GRAPHICS
  2032.  
  2033.     SetUIColor(UITEXT);
  2034.     if (drawingMode == DRAW_SCREEN)
  2035.     {
  2036.     float v[4][2];
  2037.  
  2038.     /*Draw part of button '*', the left-bottom to top-right part */
  2039.     v[0][0] = left + 2.5;
  2040.     v[0][1] = bottom + 3.5;
  2041.     v[1][0] = left + 3.5;
  2042.     v[1][1] = bottom + 2.5;
  2043.     v[2][0] = right - 2.5;
  2044.     v[2][1] = top - 3.5;
  2045.     v[3][0] = right - 3.5;
  2046.     v[3][1] = top - 2.5;
  2047.     bgnpolygon();
  2048.     v2f(v[0]);
  2049.     v2f(v[1]);
  2050.     v2f(v[2]);
  2051.     v2f(v[3]);
  2052.     endpolygon();
  2053.  
  2054.     /*Draw rest of button '*', the left-top to right-bottom part*/
  2055.     v[0][0] = left + 2.5;
  2056.     v[0][1] = top - 3.5;
  2057.     v[1][0] = left + 3.5;
  2058.     v[1][1] = top - 2.5;
  2059.     v[2][0] = right - 2.5;
  2060.     v[2][1] = bottom + 3.5;
  2061.     v[3][0] = right - 3.5;
  2062.     v[3][1] = bottom + 2.5;
  2063.     bgnpolygon();
  2064.     v2f(v[0]);
  2065.     v2f(v[1]);
  2066.     v2f(v[2]);
  2067.     v2f(v[3]);
  2068.     endpolygon();
  2069.  
  2070.     /*Draw rest of button '*', the left-to-right part*/
  2071.     v[0][0] = left + 1.5;
  2072.     v[0][1] = (top+bottom)/2.0 - 0.5;
  2073.     v[1][0] = left + 1.5;
  2074.     v[1][1] = (top+bottom)/2.0 + 0.5;
  2075.     v[2][0] = right - 1.5;
  2076.     v[2][1] = (top+bottom)/2.0 + 0.5;
  2077.     v[3][0] = right - 1.5;
  2078.     v[3][1] = (top+bottom)/2.0 - 0.5;
  2079.     bgnpolygon();
  2080.     v2f(v[0]);
  2081.     v2f(v[1]);
  2082.     v2f(v[2]);
  2083.     v2f(v[3]);
  2084.     endpolygon();
  2085.  
  2086.     /*Draw rest of button '*', the top-to-bottom part*/
  2087.     v[0][0] = (left+right)/2.0 - 0.5;
  2088.     v[0][1] = top - 1.5;
  2089.     v[1][0] = (left+right)/2.0 + 0.5;
  2090.     v[1][1] = top - 1.5;
  2091.     v[2][0] = (left+right)/2.0 + 0.5;
  2092.     v[2][1] = bottom + 1.5;
  2093.     v[3][0] = (left+right)/2.0 - 0.5;
  2094.     v[3][1] = bottom + 1.5;
  2095.     bgnpolygon();
  2096.     v2f(v[0]);
  2097.     v2f(v[1]);
  2098.     v2f(v[2]);
  2099.     v2f(v[3]);
  2100.     endpolygon();
  2101.     }
  2102.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  2103.     {
  2104.     fprintf(psFile, "%f setgray\n", PSColor());
  2105.         fprintf(psFile,
  2106.         "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n",
  2107.         left + 2.5, bottom + 3.5, left + 3.5, bottom + 2.5,
  2108.         right - 2.5, top - 3.5, right - 3.5, top - 2.5); 
  2109.         fprintf(psFile,
  2110.         "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n",
  2111.         left + 2.5, top - 3.5, left + 3.5, top - 2.5,
  2112.         right - 2.5, bottom + 3.5, right - 3.5, bottom + 2.5); 
  2113.         fprintf(psFile,
  2114.         "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n",
  2115.         left + 1.5, (top+bottom)/2.0 - 0.5, left + 1.5, (top+bottom)/2.0 + 0.5,
  2116.         right - 1.5, (top+bottom)/2.0 + 0.5, right - 1.5, (top+bottom)/2.0 - 0.5); 
  2117.         fprintf(psFile,
  2118.         "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n",
  2119.         (left+right)/2.0 - 0.5, top - 1.5, (left+right)/2.0 + 0.5, top - 1.5,
  2120.         (left+right)/2.0 + 0.5, bottom + 1.5, (left+right)/2.0 - 0.5, bottom + 1.5); 
  2121.     }
  2122. #endif /* GRAPHICS */
  2123. }
  2124.  
  2125. void    DrawMarkerBlot(left, right, bottom, top)
  2126. int     left, right, bottom, top;
  2127. {
  2128. #ifdef GRAPHICS
  2129.     SetUIColor(UITEXT);
  2130.     FillRect(left+2.5, right-2.5, bottom+2.5, top-2.5);
  2131. #endif /*GRAPHICS*/
  2132. }
  2133.  
  2134. void    DrawMarkerCheck(left, right, bottom, top)
  2135. int    left, right, bottom, top;
  2136. {
  2137. #ifdef GRAPHICS
  2138.     float v[4][2];
  2139.  
  2140.     SetUIColor(UITEXT);
  2141.     if (drawingMode == DRAW_SCREEN)
  2142.     {
  2143.     /*Draw part of checkmark*/
  2144.     v[0][0] = left + 1.5;
  2145.     v[0][1] = (top + bottom) / 2 - 0.5;
  2146.     v[1][0] = left + 2.5;
  2147.     v[1][1] = (top + bottom) / 2 + 1.5;
  2148.     v[2][0] = left + (right - left) / 3 + 1.5;
  2149.     v[2][1] = bottom + 1.5;
  2150.     v[3][0] = left + (right - left) / 3 - 0.5;
  2151.     v[3][1] = bottom + 1.5;
  2152.     bgnpolygon();
  2153.     v2f(v[0]);
  2154.     v2f(v[1]);
  2155.     v2f(v[2]);
  2156.     v2f(v[3]);
  2157.     endpolygon();
  2158.     
  2159.     /*Draw rest of checkmark*/
  2160.     v[0][0] = left + (right - left) / 3 + 1.5;
  2161.     v[0][1] = bottom + 1.5;
  2162.     v[1][0] = left + (right - left) / 3 - 0.5;
  2163.     v[1][1] = bottom + 1.5;
  2164.     v[2][0] = right - 1.5;
  2165.     v[2][1] = top - 1.5;
  2166.     bgnpolygon();
  2167.     v2f(v[0]);
  2168.     v2f(v[1]);
  2169.     v2f(v[2]);
  2170.     endpolygon();
  2171.     }
  2172.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  2173.     {
  2174.     fprintf(psFile, "%f setgray\n", PSColor());
  2175.     fprintf(psFile,
  2176.         "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n",
  2177.         left + 1.5, (top + bottom) / 2 - 0.5, left + 2.5, (top + bottom) / 2 + 1.5, 
  2178.         left + (right - left) / 3 + 1.5, bottom + 1.5, left + (right - left) / 3 - 0.5, 
  2179.         bottom + 1.5);
  2180.     fprintf(psFile, "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n", 
  2181.         left + (right - left) / 3 + 1.5, bottom + 1.5, left + (right - left) / 3 - 0.5, 
  2182.         bottom + 1.5, right - 1.5, top - 1.5);
  2183.     }
  2184. #endif /*GRAPHICS */
  2185. }
  2186.  
  2187. void    DrawMarkerX(left, right, bottom, top)
  2188. int    left, right, bottom, top;
  2189. {
  2190. #ifdef GRAPHICS
  2191.     float v[4][2];
  2192.  
  2193.     SetUIColor(UITEXT);
  2194.     /*Draw part of button 'X'*/
  2195.     v[0][0] = left + 1.5;
  2196.     v[0][1] = bottom + 2.5;
  2197.     v[1][0] = left + 2.5;
  2198.     v[1][1] = bottom + 1.5;
  2199.     v[2][0] = right - 1.5;
  2200.     v[2][1] = top - 2.5;
  2201.     v[3][0] = right - 2.5;
  2202.     v[3][1] = top - 1.5;
  2203.     bgnpolygon();
  2204.     v2f(v[0]);
  2205.     v2f(v[1]);
  2206.     v2f(v[2]);
  2207.     v2f(v[3]);
  2208.     endpolygon();
  2209.  
  2210.     /*Draw rest of button 'X'*/
  2211.     v[0][0] = left + 1.5;
  2212.     v[0][1] = top - 2.5;
  2213.     v[1][0] = left + 2.5;
  2214.     v[1][1] = top - 1.5;
  2215.     v[2][0] = right - 1.5;
  2216.     v[2][1] = bottom + 2.5;
  2217.     v[3][0] = right - 2.5;
  2218.     v[3][1] = bottom + 1.5;
  2219.     bgnpolygon();
  2220.     v2f(v[0]);
  2221.     v2f(v[1]);
  2222.     v2f(v[2]);
  2223.     v2f(v[3]);
  2224.     endpolygon();
  2225. #endif /*GRAPHICS */
  2226. }
  2227.  
  2228. #ifdef PROTO
  2229. void DrawCtlLeft(int left, int right, int bottom, int top, int uiColor)
  2230. #else
  2231. void DrawCtlLeft(left, right, bottom, top, uiColor)
  2232. int left, right, bottom, top;
  2233. Bool highlight;
  2234. #endif
  2235. {
  2236. #ifdef GRAPHICS
  2237.     float a, b, c, d;
  2238.  
  2239.     a = left - 0.5 + 1.4142 * EDGE;
  2240.     b = left - 0.5 + 0.4142 * EDGE + (top - bottom) / 2;
  2241.     c = (top + bottom) / 2;
  2242.     d = (top - bottom) / 2;
  2243.  
  2244.     /* bottom */
  2245.     SetUIColor(UIBOTTOMEDGE);
  2246.     FillRealHex(right, bottom, left + d, bottom, left, c, a, c, b, bottom + EDGE, right - EDGE, bottom + EDGE);
  2247.  
  2248.     /* top */
  2249.     SetUIColor(UITOPEDGE);
  2250.     FillRealHex(a, c, left, c, left + d, top, right, top, right - EDGE, top - EDGE, b, top - EDGE);
  2251.  
  2252.     /* right */
  2253.     SetUIColor(UIRIGHTEDGE);
  2254.     FillRealQuad(right, top, right - EDGE, top - EDGE, right - EDGE, bottom + EDGE, right, bottom);
  2255.  
  2256.     /* surface */
  2257.     SetUIColor(uiColor);
  2258.     FillRealQuint(right - EDGE, bottom + EDGE, b, bottom + EDGE, a, c, b, top - EDGE, right - EDGE, top - EDGE);
  2259. #endif
  2260. }
  2261.  
  2262. #ifdef PROTO
  2263. void DrawCtlRight(int left, int right, int bottom, int top, int uiColor)
  2264. #else
  2265. void DrawCtlRight(left, right, bottom, top, uiColor)
  2266. int left, right, bottom, top;
  2267. Bool highlight;
  2268. #endif
  2269. {
  2270. #ifdef GRAPHICS
  2271.     float a, b, c, d;
  2272.  
  2273.     a = right + 0.5 - 1.4142 * EDGE;
  2274.     b = right + 0.5 - 0.4142 * EDGE - (top - bottom) / 2;
  2275.     c = (top + bottom) / 2;
  2276.     d = (top - bottom) / 2;
  2277.  
  2278.     /* bottom */
  2279.     SetUIColor(UIBOTTOMEDGE);
  2280.     FillRealHex(right, c, right - d, bottom, left, bottom, left + EDGE, bottom + EDGE, b, bottom + EDGE, a, c);
  2281.  
  2282.     /* top */
  2283.     SetUIColor(UITOPEDGE);
  2284.     FillRealHex(right, c, a, c, b, top - EDGE, left + EDGE, top - EDGE, left, top, right - d, top);
  2285.  
  2286.     /* left */
  2287.     SetUIColor(UILEFTEDGE);
  2288.     FillRealQuad(left, bottom, left, top, left + EDGE, top - EDGE, left + EDGE, bottom + EDGE);
  2289.  
  2290.     /* surface */
  2291.     SetUIColor(uiColor);
  2292.     FillRealQuint(a, c, b, bottom + EDGE, left + EDGE, bottom + EDGE, left + EDGE, top - EDGE, b, top - EDGE);
  2293. #endif
  2294. }
  2295.  
  2296. #ifdef PROTO
  2297. void DrawCtlUp(int left, int right, int bottom, int top, int uiColor)
  2298. #else
  2299. void DrawCtlUp(left, right, bottom, top, uiColor)
  2300. int left, right, bottom, top;
  2301. Bool highlight;
  2302. #endif
  2303. {
  2304. #ifdef GRAPHICS
  2305.     float a, b, c, d;
  2306.  
  2307.     a = top - 1.4142 * EDGE + 0.5;
  2308.     b = top - 0.4142 * EDGE - (right - left) /2;
  2309.     c = (right + left) / 2;
  2310.     d = (right - left) / 2;
  2311.  
  2312.     /* left */
  2313.     SetUIColor(UILEFTEDGE);
  2314.     FillRealHex(c, top, c, a, left + EDGE, b, left + EDGE, bottom + EDGE, left, bottom, left, top - d);
  2315.  
  2316.     /* right */
  2317.     SetUIColor(UIRIGHTEDGE);
  2318.     FillRealHex(c, top, right, top - d, right, bottom, right - EDGE, bottom + EDGE, right - EDGE, b, c, a);
  2319.  
  2320.     /* bottom */
  2321.     SetUIColor(UIBOTTOMEDGE);
  2322.     FillRealQuad(right, bottom, left, bottom, left + EDGE, bottom + EDGE, right - EDGE, bottom + EDGE);
  2323.  
  2324.     /* surface */
  2325.     SetUIColor(uiColor);
  2326.     FillRealQuint(c, a, right - EDGE, b, right - EDGE, bottom + EDGE, left + EDGE, bottom + EDGE, left + EDGE, b);
  2327. #endif
  2328. }
  2329.  
  2330. #ifdef PROTO
  2331. void DrawCtlDown(int left, int right, int bottom, int top, int uiColor)
  2332. #else
  2333. void DrawCtlDown(left, right, bottom, top, uiColor)
  2334. int left, right, bottom, top;
  2335. Bool highlight;
  2336. #endif
  2337. {
  2338. #ifdef GRAPHICS
  2339.     float a, b, c, d;
  2340.  
  2341.     a = bottom + 1.4142 * EDGE - 0.5;
  2342.     b = bottom + 0.4142 * EDGE - (right - left) /2;
  2343.     c = (right + left) / 2;
  2344.     d = (right - left) / 2;
  2345.  
  2346.     /* left */
  2347.     SetUIColor(UILEFTEDGE);
  2348.     FillRealHex(c, bottom, left, bottom + d, left, top, left + EDGE, top - EDGE, left + EDGE, b, c, a);
  2349.  
  2350.     /* right */
  2351.     SetUIColor(UIRIGHTEDGE);
  2352.     FillRealHex(c, bottom, c, a, right - EDGE, b, right - EDGE, top - EDGE, right, top, right, bottom + d);
  2353.  
  2354.     /* top */
  2355.     SetUIColor(UITOPEDGE);
  2356.     FillRealQuad(right, top, right - EDGE, top - EDGE, left + EDGE, top - EDGE, left, top);
  2357.  
  2358.     /* surface */
  2359.     SetUIColor(uiColor);
  2360.     FillRealQuint(c, a, left + EDGE, b, left + EDGE, top - EDGE, right - EDGE, top - EDGE, right - EDGE, b);
  2361. #endif
  2362. }
  2363.  
  2364. #ifdef PROTO
  2365. void SavePSImage(FILE *psFile, Pixel *imageBuffer, int left, int right, int bottom, int top)
  2366. #else
  2367. void SavePSImage(psFile, imageBuffer, left, right, bottom, top)
  2368. FILE *psFile;
  2369. Pixel *imageBuffer;
  2370. int left;
  2371. int right;
  2372. int bottom;
  2373. int top;
  2374. #endif
  2375. /*Saves an image in imageBuffer within left, right, bottom, top into psFile*/
  2376. {
  2377.     real y, dummy;
  2378.     int iVal;
  2379.     long k;
  2380.     int pixWrap;
  2381.     long nPixels;
  2382.     long i, j, ip, jp;
  2383.     long width, height;
  2384.     int subSample;
  2385.  
  2386.     subSample = imageSubSample + 1;
  2387.  
  2388.  
  2389.     width = right - left;
  2390.     height = top - bottom;
  2391.  
  2392. #define PIXPERLINE    10
  2393.  
  2394. #ifdef COLORPOST
  2395.     /*Color image.  Do stuff before pixels*/
  2396.     fprintf(psFile, "%% Color Space image within %d %d %d %d\n",
  2397.         left, right, bottom, top);
  2398.     fprintf(psFile, "%d %d moveto\n", left, bottom);
  2399.     fprintf(psFile, "/imgstr %d string def\n", 3 * width);
  2400.     fprintf(psFile, "%d %d %d matrix \n", right - left, top - bottom, 8);
  2401.  
  2402.     /*Do pixels*/
  2403.     nPixels = width * height;
  2404.     pixWrap = 0;
  2405.     fprintf(psFile, "{currentfile imgstr readhexstring pop} false 3 colorimage\n");
  2406.     for (k = 0; k < nPixels; ++k)
  2407.     {
  2408.     fprintf(psFile, "%02X%02X%02X%s",
  2409.         LinToGamma[imageBuffer[k] . red],
  2410.         LinToGamma[imageBuffer[k] . green],
  2411.         LinToGamma[imageBuffer[k] . blue],
  2412.         (++pixWrap) % PIXPERLINE ? " " : "\n");
  2413.     }
  2414.     fprintf(psFile, "\n\n");
  2415. #else
  2416.     /*B/W image.  Do stuff before pixels*/
  2417.     fprintf(psFile, "%% B/W Space image within %d %d %d %d\n",
  2418.         left, right, bottom, top);
  2419.     fprintf(psFile, "/imgstr %d string def\n", width / subSample);
  2420.     fprintf(psFile, "%d %d %d\n", width / subSample, height / subSample, 8);
  2421.     fprintf(psFile, "%d %d matrix translate\n",
  2422.         -left, -bottom);
  2423.     fprintf(psFile, "%lg %lg matrix scale\n",
  2424.         1.0 / (double) subSample, 1.0 / (double) subSample);
  2425.     fprintf(psFile, " matrix concatmatrix\n");
  2426.  
  2427.     /*Do pixels*/
  2428.     nPixels = (right - left) * (top - bottom);
  2429.     pixWrap = 0;
  2430.     fprintf(psFile, "{currentfile imgstr readhexstring pop} image\n");
  2431.  
  2432.  
  2433.     for (j = 0; j < height; j += subSample)
  2434.     {
  2435.     for (i = 0; i < width; i += subSample)
  2436.     {
  2437.         real avgPixel;
  2438.  
  2439.         avgPixel = 0.0;
  2440.  
  2441.         /*Calculate an average pixel*/
  2442.         for (jp = j; jp < j + subSample; ++jp)
  2443.         {
  2444.         for (ip = i; ip < i + subSample; ++ip)
  2445.         {
  2446.             k = ip + jp * width;
  2447.  
  2448.             RGB2YIQ(&y, &dummy, &dummy,
  2449.             imageBuffer[k] . red / 255.0,
  2450.             imageBuffer[k] . green / 255.0,
  2451.             imageBuffer[k] . blue / 255.0);
  2452.  
  2453.             avgPixel += y;
  2454.         }
  2455.         }
  2456.         avgPixel /= (real) subSample;
  2457.         avgPixel /= (real) subSample;
  2458.  
  2459.         iVal = avgPixel * 255.0;
  2460.         if (iVal < 0) iVal = 0;
  2461.         if (iVal > 255) iVal = 255;
  2462.         fprintf(psFile, "%02X%s", LinToGamma[iVal],
  2463.         (++pixWrap) % PIXPERLINE ? " " : "\n");
  2464.     }
  2465.     }
  2466.  
  2467.     fprintf(psFile, "\n\n");
  2468.  
  2469. #endif
  2470.  
  2471. #undef PIXPERLINE
  2472.  
  2473. }
  2474.  
  2475. /*
  2476.  * Icons in eps files 10/28/92
  2477.  * In order to make the eps file of a window self contained, a bit-mapped
  2478.  * font of just the icons used in that window is defined in the file. In PS
  2479.  * drawing mode, RegisterIconUsed keeps a list of the icon numbers used.
  2480.  * It returns the index of the icon in the list. EndDrawing uses the list
  2481.  * to create the font definition. If there are any icons in the window, the
  2482.  * file must be rewritten with the font definition in the header. The font
  2483.  * definition is generated by GenIconDef() in ScianIcons.c.
  2484.  */
  2485.  
  2486. #ifdef PROTO
  2487. void DrawPSFrame(char *name, int left, int right, int bottom, int top)
  2488. #else
  2489. void DrawPSFrame(name, left, right, bottom, top)
  2490. char *name;
  2491. int left;
  2492. int right;
  2493. int bottom;
  2494. int top;
  2495. #endif
  2496. /*Draws a PostScript frame around left, right, bottom, top*/
  2497. {
  2498.     left -= WINFRAMEWID;
  2499.     right -= WINFRAMEWID;
  2500.     bottom -= WINFRAMEWID;
  2501.     top -= WINFRAMEWID;
  2502.     {
  2503.         /* draw a generic window frame with title only */
  2504.         fprintf(psFile,
  2505. "newpath 0 0 moveto 0 %d lineto %d %d lineto %d 0 lineto closepath stroke\n", 
  2506.         top, right, top, right);
  2507.         fprintf(psFile, 
  2508. "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath stroke\n", 
  2509.         WINFRAMEWID - 1, WINFRAMEWID - 1,
  2510.         WINFRAMEWID - 1, top - WINFRAMEWID + 1,
  2511.         right - WINFRAMEWID + 1, top - WINFRAMEWID + 1,
  2512.         right - WINFRAMEWID + 1, WINFRAMEWID - 1);
  2513.         fprintf(psFile, "newpath %d %d moveto %d %d lineto stroke\n", 
  2514.         WINFRAMEWID - 1, top - WINFRAMEWID - WINTITLEHT + 1, 
  2515.         right - WINFRAMEWID + 1, top - WINFRAMEWID - WINTITLEHT + 1);
  2516.         SetupFont(WINTITLEFONT, 12);
  2517.         fprintf(psFile, "%d %d moveto (%s) show\n", 
  2518.         WINFRAMEWID + 20, top - WINFRAMEWID - WINTITLEHT + 5, show(name));
  2519.         RegisterFontUsed(WINTITLEFONT);
  2520.     }
  2521. }
  2522.  
  2523. #ifdef PROTO
  2524. void BeginDrawSubscreen(int ox, int oy)
  2525. #else
  2526. void BeginDrawSubscreen(ox, oy)
  2527. int ox, oy;
  2528. #endif
  2529. /*Begins a drawing segment offset by ox, oy*/
  2530. {
  2531.     if (drawingMode == DRAW_POSTSCRIPT && psFile)
  2532.     {
  2533.     fprintf(psFile, "%d %d translate\n", ox, oy);
  2534.     }
  2535. }
  2536.  
  2537. #ifdef PROTO
  2538. void EndDrawSubscreen(int ox, int oy)
  2539. #else
  2540. void EndDrawSubscreen(ox, oy)
  2541. int ox, oy;
  2542. #endif
  2543. /*Begins a drawing segment offset by ox, oy*/
  2544. {
  2545.     if (drawingMode == DRAW_POSTSCRIPT && psFile)
  2546.     {
  2547.     fprintf(psFile, "%d %d translate\n", -ox,  -oy);
  2548.     }
  2549. }
  2550.  
  2551. #ifdef PROTO
  2552. void BeginDrawing(char *name, int left, int right, int bottom, int top, real scale)
  2553. #else
  2554. void BeginDrawing(name, left, right, bottom, top, scale)
  2555. char *name;            /*Window title*/
  2556. int left, right, bottom, top;    /*Coordinates of window INTERIOR*/
  2557. real scale;
  2558. #endif
  2559. {
  2560. #ifdef GRAPHICS
  2561.     psFile = tmpfile();
  2562.     if (drawingMode == DRAW_POSTSCRIPT && psFile)
  2563.     {
  2564.     struct timeval date;
  2565.  
  2566.         gettimeofday(&date, (struct timezone *)0);
  2567.     
  2568.     /* "normalize" bounds */
  2569.     right -= left;
  2570.     top -= bottom;
  2571.  
  2572.     /* initialize counters */
  2573.     numFontsUsed = 0;
  2574.     numIconsUsed = 0;
  2575.  
  2576.         /* write EPS header */
  2577.         fprintf(psFile,
  2578. "\
  2579. %%!PS-Adobe-2.0 EPSF-2.0\n\
  2580. %%%%Title: %s\n\
  2581. %%%%Creator: SciAn\n\
  2582. %%%%CreationDate: %s\
  2583. %%%%For: %s\n\
  2584. %%%%DocumentFonts: (atend)\n\
  2585. %%%%BoundingBox: 0 0 %d %d\n\
  2586. %%%%EndComments\n\
  2587. save\n\n",    /* NOTE: icon font def is inserted after first blank line of file */
  2588.         name, ctime(&date.tv_sec), getenv("USER"),
  2589.         (int) (scale * (real) (right + 1)), (int) (scale * (real) (top + 1)));
  2590.     
  2591.     fprintf(psFile, 
  2592. "/resetclip {matrix currentmatrix currentfont currentlinewidth\n\
  2593. grestore gsave setlinewidth setfont setmatrix } def\n\
  2594. \n\
  2595. currentscreen 3 1 roll pop pop 75 0 3 -1 roll setscreen\n\
  2596. gsave\n\
  2597. 1 setlinewidth\n\
  2598. %g %g scale\n\n\n", scale, scale);
  2599.  
  2600.     }
  2601. #endif
  2602. }
  2603.  
  2604. #ifdef PROTO
  2605. void EndDrawing(Bool showpagep)
  2606. #else
  2607. void EndDrawing(showpagep)
  2608. Bool showpagep;
  2609. #endif
  2610. {
  2611. #ifdef GRAPHICS
  2612.     if (drawingMode == DRAW_POSTSCRIPT && psFile && drawFile)
  2613.     {
  2614.     char buf[256];
  2615.         int i;
  2616.     
  2617.     /* copy header from temp file (copies to first blank line) */
  2618.     rewind(psFile);
  2619.     while (fgets(buf, 256, psFile))
  2620.     {
  2621.         fputs(buf, drawFile);
  2622.         if (*buf == '\n') break;
  2623.     }
  2624.     
  2625.     /* generate font of icons used, if needed */
  2626.     GenIconDef(drawFile);
  2627.     
  2628.     /* copy the rest of the temp file */
  2629.     while (fgets(buf, 256, psFile))
  2630.     {
  2631.         fputs(buf, drawFile);
  2632.     }
  2633.     fclose(psFile);
  2634.  
  2635.     if (showpagep)
  2636.     {
  2637.         fprintf(drawFile, "\nshowpage\n");
  2638.     }
  2639.  
  2640.         /* write PostScript trailer -- list fonts used */
  2641.         fprintf(drawFile, "\nrestore\n\n%%%%Trailer\n%%%%DocumentFonts:");
  2642.     for (i=0; i<numFontsUsed; ++i)
  2643.         {
  2644.             fprintf(drawFile, " %s", fontsUsed[i]);
  2645.  
  2646.         /* free the fontsUsed string space */
  2647.             Free(fontsUsed[i]);
  2648.             fontsUsed[i] = NIL;
  2649.         }
  2650.         fprintf(drawFile, "\n");
  2651.     }
  2652. #endif
  2653. }
  2654.  
  2655. #ifdef PROTO
  2656. int RegisterIconUsed(int icon)
  2657. #else
  2658. int RegisterIconUsed(icon)
  2659. int icon;
  2660. #endif
  2661. {
  2662. #ifdef GRAPHICS
  2663.     int i;
  2664.  
  2665.     /* check list of icons used */
  2666.     for (i = 0; i < numIconsUsed; ++i)
  2667.     {
  2668.         if (icon == iconsUsed[i]) return i; /* already got it */
  2669.     }
  2670.     if (numIconsUsed >= 32)
  2671.     {
  2672.         ReportError("RegisterIconUsed","Too many different icons!");
  2673.         return -1;
  2674.     }
  2675.     iconsUsed[numIconsUsed] = icon;
  2676.     return numIconsUsed++;
  2677. #else
  2678.     return 0;
  2679. #endif
  2680. }
  2681.  
  2682. void EraseAll()
  2683. /*Erases everything*/
  2684. {
  2685.     SetUIColor(UIBLACK);
  2686.     clear();
  2687. }
  2688.  
  2689. void InitDraw()
  2690. /*Initializes the drawing system*/
  2691. {
  2692.     int k;
  2693.  
  2694.     /*No window at the beginning*/
  2695.     curDrawingStateIndex = 0;
  2696.     CURSTATE . window = 0;
  2697.     CURSTATE . initialWindow = false;
  2698.     for (k = 0; k < 4; ++k)
  2699.     {
  2700.     CURSTATE . screenMask[k] = 0;
  2701.     CURSTATE . viewport[k] = 0;
  2702.     }
  2703.     for (k = 0; k < 2; ++k)
  2704.     {
  2705.     CURSTATE . origin[k] = 0;
  2706.     CURSTATE . translation[k] = 0;
  2707.     }
  2708. }
  2709.  
  2710. void KillDraw()
  2711. {
  2712. }
  2713.